http://codeforces.com/contest/1236
C. Labs
题意:把 1到 n 2 n^2 n 2 分成n组,组间连边,且只有从大数向小数连有向边,要求最大化两组之间边数的最小值。
直接猜蛇形构造。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <bits/stdc++.h> using namespace std;#define ll long long const int N = 2e5 + 10 ;const int INF = 0x3f3f3f3f ;int n;int a[310 ][310 ];int main () { scanf ("%d" , &n); int p = 1 , ad = 1 ; for (int i = 1 ; i <= n * n; i++) { int t = (i - 1 ) / n + 1 ; a[p][t] = i; if (p == n && (t & 1 ) || p == 1 && (!(t & 1 )))continue ; if (t & 1 )p++; else p--; } for (int i = 1 ; i <= n; i++) { for (int j = 1 ; j <= n; j++)printf ("%d%s" , a[i][j], j == n ? "\n" : " " ); } return 0 ; }
D. Alice and the Doll
题意:nm网格,从左上角出发,要走遍所有非障碍物的格子,每次只能右转或直走,且每一格内只能右转一次,问是否可以经过非障碍每一格一次。
从起点走只能向右直走到底否则就走不出自己经过的轨迹了,再发现每一点都是这样,只能走到底转弯。
所以固定只能螺旋走位,那就是个大模拟题,判断能走的格子数+障碍数是否为总数。
但是由于复杂度不能nm暴力,所以模拟时要跳着走,直接跳到障碍或者边界去。
维护每一行以及每一列的障碍,再维护外侧的矩形,矩形不断缩小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <bits/stdc++.h> using namespace std;#define ll long long const int N = 1e5 + 10 ;int n, m, K;ll ans; vector <int > X[N], Y[N]; int main () { scanf ("%d%d%d" , &n, &m, &K); for (int i = 1 ; i <= K; i++){ int a, b; scanf ("%d%d" , &a, &b); X[a].push_back (b); Y[b].push_back (a); } for (int i = 1 ; i <= n; i++) sort (X[i].begin (), X[i].end ()); for (int i = 1 ; i <= m; i++) sort (Y[i].begin (), Y[i].end ()); int x = 1 , y = 1 , k = 1 , flag = 0 ; ans++; int xL = 0 , xR = n + 1 , yL = 0 , yR = m + 1 ; while (1 ){ int tx = 0 , ty = 0 ; if (k == 1 ){ tx = x, ty = lower_bound (X[x].begin (), X[x].end (), y) - X[x].begin (); if (ty == X[x].size ()) ty = yR - 1 ; else ty = min (yR - 1 , X[x][ty] - 1 ); k = 2 ; xL = x; } else if (k == 2 ){ tx = lower_bound (Y[y].begin (), Y[y].end (), x) - Y[y].begin (), ty = y; if (tx == Y[y].size ()) tx = xR - 1 ; else tx = min (xR - 1 , Y[y][tx] - 1 ); k = 3 ; yR = y; } else if (k == 3 ){ tx = x, ty = lower_bound (X[x].begin (), X[x].end (), y) - X[x].begin () - 1 ; if (ty < 0 ) ty = yL + 1 ; else ty = max (yL + 1 , X[x][ty] + 1 ); k = 4 ; xR = x; } else if (k == 4 ){ tx = lower_bound (Y[y].begin (), Y[y].end (), x) - Y[y].begin () - 1 , ty = y; if (tx < 0 ) tx = xL + 1 ; else tx = max (xL + 1 , Y[y][tx] + 1 ); k = 1 ; yL = y; } if (x == tx && y == ty && flag) break ; ans += abs (x - tx) + abs (y - ty); x = tx, y = ty; flag = 1 ; } if (ans == 1ll * n*m - K) printf ("Yes\n" ); else printf ("No\n" ); return 0 ; }