Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- http://usaco.org/index.php?page=viewproblem2&cpid=1065
- I thought the robots all move in a single direction randomly chosen at the start.
- I didn't realize they could actually change direction at any point.
- This solution works for the first case.
- Two hours wasted FeelsBadMan
- */
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef pair<int, int> pii;
- const int EMPTY = 0, WALL = 1, START = 2;
- const int MAXN = 1000;
- int N, D;
- int grid[MAXN][MAXN];
- int cumres[MAXN][MAXN]; // CUMULATIVE, not the other word
- typedef pair<pii, int> piii;
- int maxreach[MAXN][MAXN];
- piii dp[MAXN][MAXN]; // ((r, c), distance)
- pii status[MAXN][MAXN]; // (iterations left, reach at end)
- int pref[MAXN][MAXN];
- void PRINT(string s, int a[MAXN][MAXN]) {
- cout << s << ":\n";
- for (int r = 0; r < N; ++r) {
- for (int c = 0; c < N; ++c) {
- cout << setw(2) << right << a[r][c] << ' ';
- }
- cout << '\n';
- }
- }
- string TOSTRING(pii a) {
- return "(" + to_string(a.first) + "," + to_string(a.second) + ")";
- }
- string TOSTRING(piii a) {
- return "((" + to_string(a.first.first) + "," + to_string(a.first.second) + ")," + to_string(a.second) + ")";
- }
- void DFS(int r, int c) {
- cout << "DFS("<<r<<","<<c<<"),mr="<<maxreach[r][c]<<",dp="<<TOSTRING(dp[r][c])<<"\n";
- if (maxreach[r][c] < D+1) return;
- if (r > 0 && dp[r][c].first == dp[r-1][c+D].first) {
- DFS(r-1, c+D);
- } else if (r+1 < N && dp[r][c].first == dp[r+1][c+D].first) {
- DFS(r+1, c+D);
- } else {
- DFS(r, c+D+1);
- }
- }
- inline void update_node(piii& a, piii b) {
- if (b.second < a.second) {
- a = b;
- } else if (b.second == a.second) {
- if (maxreach[b.first.first][b.first.second]
- < maxreach[a.first.first][a.first.second]) {
- a = b;
- }
- }
- }
- inline void update_status(pii& a, pii b) {
- if (b.first > a.first) {
- a = b;
- } else if (b.first == a.first && b.second > a.second) {
- a = b;
- }
- }
- void solve() {
- PRINT("grid", grid);
- vector<int> nxt(N), nxt2(N);
- for (int c = N-1; c >= 0; --c) {
- for (int r = 0; r < N; ++r) {
- nxt[r] = (grid[r][c] == WALL) ? c : nxt2[r];
- if (nxt[r] <= c+D) { // not full strip
- maxreach[r][c] = nxt[r] - c;
- dp[r][c] = make_pair(make_pair(r, c), 0);
- } else {
- maxreach[r][c] = D+1;
- dp[r][c] = dp[r][c+D+1];
- if (r > 0) update_node(dp[r][c], dp[r-1][c+D]);
- if (r+1 < N) update_node(dp[r][c], dp[r+1][c+D]);
- dp[r][c].second += 1; // INCREASE DISTANCE BY 1
- }
- status[r][c].first = -1;
- pref[r][c] = 0;
- }
- swap(nxt, nxt2);
- }
- PRINT("maxreach", maxreach);
- DFS(3, 1);
- for (int c = 0; c < N; ++c) {
- for (int r = 0; r < N; ++r) {
- if (grid[r][c] == START) {
- int r1 = dp[r][c].first.first;
- int c1 = dp[r][c].first.second;
- update_status( status[r][c],
- make_pair(dp[r][c].second, maxreach[r1][c1]));
- cout<<"Start("<<r<<","<<c<<")\n";
- }
- int iter = status[r][c].first;
- if (iter == -1) continue;
- int reach = iter > 0 ? D+1 : status[r][c].second;
- cout << "r="<<r<<" c="<<c<<" status="<<TOSTRING(status[r][c])<<"\n";
- cout << "pref adding "<<r<<"["<<c<<","<<c+reach<<"]\n";
- pref[r][c] += 1;
- pref[r][c + reach] -= 1;
- if (iter > 0) {
- update_status(status[r][c+D+1], make_pair(iter-1, status[r][c].second));
- update_status(status[r-1][c+D], make_pair(iter-1, status[r][c].second));
- update_status(status[r+1][c+D], make_pair(iter-1, status[r][c].second));
- }
- }
- }
- for (int r = 0; r < N; ++r) {
- int x = 0;
- for (int c = 0; c < N; ++c) {
- x += pref[r][c];
- cumres[r][c] += x;
- }
- }
- PRINT("cumres", cumres);
- cout<<"\n";
- }
- void rotate_90(int g[MAXN][MAXN]) {
- static int temp[MAXN][MAXN];
- for (int i = 0; i < N; ++i) {
- for (int j = 0; j < N; ++j) {
- temp[j][N-1-i] = g[i][j];
- }
- }
- for (int i = 0; i < N; ++i) {
- for (int j = 0; j < N; ++j) {
- g[i][j] = temp[i][j];
- }
- }
- }
- int main() {
- ios::sync_with_stdio(false);
- cin.tie(0);
- cin >> N >> D;
- for (int r = 0; r < N; ++r) {
- for (int c = 0; c < N; ++c) {
- char ch;
- cin >> ch;
- if (ch == '.') grid[r][c] = EMPTY;
- else if (ch == '#' || ch == 'X') grid[r][c] = WALL;
- else grid[r][c] = START;
- cumres[r][c] = 0;
- }
- }
- for (int i = 0; i < 4; ++i) {
- solve();
- //break;
- rotate_90(grid);
- rotate_90(cumres);
- }
- int ans = 0;
- for (int r = 0; r < N; ++r)
- for (int c = 0; c < N; ++c)
- if (cumres[r][c] > 0)
- ++ans;
- cout << ans << '\n';
- }
- /*
- (13)
- 7 2
- XXXXXXX
- X.....X
- X.....X
- XS....X
- X.....X
- X.....X
- XXXXXXX
- (15)
- 10 1
- ##########
- #........#
- #S.......#
- #........#
- ##########
- #S....S..#
- ##########
- ##########
- ##########
- ##########
- (28)
- 10 2
- ##########
- #.#......#
- #.#......#
- #S.......#
- #.#......#
- #.#......#
- ##########
- ##########
- ##########
- ##########
- (10)
- 10 2
- ##########
- #.S#.....#
- #..#.....#
- #S.......#
- #..#.....#
- #..#.....#
- ##########
- ##########
- ##########
- ##########
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement