Spaced Out USACO 2021 January Contest

Spaced Out USACO Solution

Farmer John wants to take a picture of his cows grazing in their pasture to hang on his wall. The pasture is represented by an NN by NN grid of square cells (picture an N×NN×N chess board), with 2≤N≤10002≤N≤1000. In the last picture Farmer John took, his cows were too clumped together in one region of the pasture.

See Also: USACO 2021 January Contest

This time around, he wants to make sure his cows are properly spaced out across the pasture. He therefore insists on the following rules:

  • No two cows may be placed in the same cell.
  • Every sub-grid of 2×22×2 cells ((N−1)×(N−1)(N−1)×(N−1) of them in total) must contain exactly 2 cows.

For example, this placement is valid:

CCC
...
CCC

while this placement is not, because the 2×22×2 square region that contains the bottom-right corner cell contains only 1 cow:

C.C
.C.
C..

There are no other restrictions. You may assume that Farmer John has an infinite number of cows available (based on previous experience, this assumption certainly seems to be true…).

Farmer John wants some cells to contain cows more than other cells. In particular, he believes that when a cow is placed in cell (i,j)(i,j), the beauty of the picture is increased by aijaij (0≤aij≤10000≤aij≤1000) units.

Determine the maximum possible total beauty of a valid placement of cows.

INPUT FORMAT (input arrives from the terminal / stdin):

The first line contains NN. The next NN lines contain NN integers each. The jjth integer of the iith line from the top is the value of aijaij.

OUTPUT FORMAT (print output to the terminal / stdout):

Print one integer giving the maximum possible beauty of the resulting photo.

SAMPLE INPUT:

4
3 3 1 1
1 1 3 1
3 3 1 1
1 1 3 3

SAMPLE OUTPUT:

22

In this sample, the maximum beauty can be achieved with the following placement:

CC..
..CC
CC..
..CC

The beauty of this placement is 3+3+3+1+3+3+3+3=223+3+3+1+3+3+3+3=22.

SCORING:

  • Test cases 2-4 satisfy N≤4N≤4.
  • Test cases 5-10 satisfy N≤10N≤10.
  • Test cases 11-20 satisfy N≤1000N≤1000.

Problem credits: Hankai Zhang and Danny Mittal

Solution

The key observation is that in any valid arrangement, either every row will alternate between cow and no-cow, or every column will alternate between cow and no-cow.

Proof:

If no two cows are adjacent to each other, the statement is obviously met (both rows and columns will alternate in this case).

Otherwise, suppose there are two cows next to each other. Assume without loss of generality that they are horizontally adjacent.

?????
?CC??
?????
?????
?????

It is not hard to see that the only way to fill up the columns that these two cows occupy is by alternating between cow and no-cow:

?..??
?CC??
?..??
?CC??
?..??

Now we have to fill up the remaining columns. Start from either column adjacent to an already-filled column. We notice that they also have to be filled by alternating between cow and no-cow; otherwise, there will always be a 2 by 2 square that has 1 cow or 3 cows. This holds true for every remaining column that we fill. Thus, the statement is proven.

C..C.
.CC.C
C..C.
.CC.C
C..C.

To solve the problem, we just consider both cases (rows alternating or columns alternating), and for each row/column, select the arrangement (there are only two of them, because it must be alternating) that results in the maximum beauty.

For partial credit, we can iterate over all possible arrangements of cows (2N+1−22N+1−2 of them in total).

Danny’s C++ code:

#include <iostream>
 
#define ll long long
 
using namespace std;
 
ll grid[1000][1000];
 
int main() {
    int n;
    cin >> n;
    for (int y = 0; y < n; y++) {
        for (int x = 0; x < n; x++) {
            cin >> grid[y][x];
        }
    }
    ll horizontalAnswer = 0;
    for (int y = 0; y < n; y++) {
        ll sums[2];
        sums[0] = 0;
        sums[1] = 0;
        for (int x = 0; x < n; x++) {
            sums[x % 2] += grid[y][x];
        }
        horizontalAnswer += max(sums[0], sums[1]);
    }
    ll verticalAnswer = 0;
    for (int x = 0; x < n; x++) {
        ll sums[2];
        sums[0] = 0;
        sums[1] = 0;
        for (int y = 0; y < n; y++) {
            sums[y % 2] += grid[y][x];
        }
        verticalAnswer += max(sums[0], sums[1]);
    }
    cout << max(horizontalAnswer, verticalAnswer) << "\n";
    return 0;
}

Danny’s Java code:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class CowPlacementsModelSolution {
 
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(in.readLine());
        long[][] grid = new long[n][n];
        for (int y = 0; y < n; y++) {
            StringTokenizer tokenizer = new StringTokenizer(in.readLine());
            for (int x = 0; x < n; x++) {
                grid[y][x] = Long.parseLong(tokenizer.nextToken());
            }
        }
        long horizontalAnswer = 0;
        for (int y = 0; y < n; y++) {
            long[] sums = new long[2];
            for (int x = 0; x < n; x++) {
                sums[x % 2] += grid[y][x];
            }
            horizontalAnswer += Math.max(sums[0], sums[1]);
        }
        long verticalAnswer = 0;
        for (int x = 0; x < n; x++) {
            long[] sums = new long[2];
            for (int y = 0; y < n; y++) {
                sums[y % 2] += grid[y][x];
            }
            verticalAnswer += Math.max(sums[0], sums[1]);
        }
        System.out.println(Math.max(horizontalAnswer, verticalAnswer));
    }
}

USACO 2021 January Contest Solution

Leave a Comment