Whenever there exists a cow horizontally or vertically adjacent to three other cows, Farmer Nhoj is forced to place a cow at the fourth spot.
... .C. CCC -> CCC .C. .C.
So this is essentially a flood fill problem; while there exists a location that should contain a cow but does not, add a cow at that location.
My solution maintains a 2D boolean array of which locations currently contain cows, as well as a queue of locations in the pasture where a cow needs to be added. While the queue is nonempty, pop the top element (x,y) of the queue and check whether a cow has already been added at (x,y). If not, add the cow at (x,y), and check whether any of the locations (x,y),(x,y−1),(x,y+1),(x−1,y),(x+1,y) contain cows and are adjacent to exactly three cows. If so, add all such locations to the queue and repeat.
Additional notes:
Time Complexity: O(N+(grid size)2).
#include <bits/stdc++.h> using namespace std; #define f first #define s second const int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1}; bool present[3000][3000]; // which locations contain cows int main() { int N; cin >> N; queue<pair<int,int>> cows_to_place; int total_cows = 0; for (int initial_cows = 1; initial_cows <= N; ++initial_cows) { pair<int,int> p; cin >> p.f >> p.s; p.f += 1000, p.s += 1000; cows_to_place.push(p); auto re_evaluate = [&](int x, int y) { // if cow adjacent to exactly three others // add fourth location to queue if (!present[x][y]) return; int num_adj = 0; for (int d = 0; d < 4; ++d) num_adj += present[x+dx[d]][y+dy[d]]; if (num_adj == 3) for (int d = 0; d < 4; ++d) { pair<int,int> nex{x+dx[d],y+dy[d]}; if (!present[nex.f][nex.s]) cows_to_place.push(nex); } }; while (!cows_to_place.empty()) { pair<int,int> loc = cows_to_place.front(); cows_to_place.pop(); if (present[loc.f][loc.s]) continue; ++ total_cows; present[loc.f][loc.s] = 1; re_evaluate(loc.f,loc.s); for (int d = 0; d < 4; ++d) re_evaluate(loc.f+dx[d],loc.s+dy[d]); } cout << total_cows-initial_cows << "\n"; } }
Here is an alternative solution by Danny Mittal that does not use a queue:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class LonelyPastureSilver { static final boolean[][] cows = new boolean[3000][3000]; static final int[][] adj = new int[3000][3000]; static int answer = 0; static void add(int x, int y) { if (!cows[x][y]) { cows[x][y] = true; answer++; if (cows[x][y] && adj[x][y] == 3) { for (int[] another : new int[][]{{x - 1, y}, {x + 1, y}, {x, y - 1}, {x, y + 1}}) { int w = another[0]; int z = another[1]; add(w, z); } } for (int[] other : new int[][]{{x - 1, y}, {x + 1, y}, {x, y - 1}, {x, y + 1}}) { int u = other[0]; int v = other[1]; adj[u][v]++; if (cows[u][v] && adj[u][v] == 3) { for (int[] another : new int[][]{{u - 1, v}, {u + 1, v}, {u, v - 1}, {u, v + 1}}) { int w = another[0]; int z = another[1]; add(w, z); } } } } } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); StringBuilder out = new StringBuilder(); int n = Integer.parseInt(in.readLine()); for (int j = 0; j < n; j++) { StringTokenizer tokenizer = new StringTokenizer(in.readLine()); int x = Integer.parseInt(tokenizer.nextToken()) + 1000; int y = Integer.parseInt(tokenizer.nextToken()) + 1000; answer--; add(x, y); out.append(answer).append('\n'); } System.out.print(out); } }