题意。。。上ceoi官网看吧。。。
首先打一下sg函数发现必胜态和必败态的分布位置是有规律的
于是我们只要知道最长步数的必胜态和最长步数的必败态哪个更长就可以了
然后再打一下步数的表。。。发现必败态的最长步数非常好确定,那么必胜态的步数搜一下就可以了!
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 /************************************************************** 2 Problem: 1393 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:992 ms 7 Memory:2372 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 13 using namespace std; 14 const int dx[] = {-2, -2, -1, 1}; 15 const int dy[] = {1, -1, -2, -2}; 16 const int N = 2e5 + 5; 17 const int inf = 1e8; 18 19 int n, k; 20 int Ans, ansx[N], ansy[N]; 21 22 inline int read(); 23 inline void print (const int &); 24 25 inline bool calc_sg(int x, int y) { 26 if ((x % 4 == 1 || x % 4 == 2) && (y % 4 == 1 || y % 4 == 2)) return 0; 27 if (n % 4 == 1 && ((x == n && y != n - 1) || (y == n && x != n - 1))) return 0; 28 if (n % 4 == 0 && x == n && y == n) return 0; 29 return 1; 30 } 31 32 inline bool in(const int &x, const int &y) { 33 return (x > 0 && y > 0 && x <= n && y <= n); 34 } 35 36 #define X x + dx[k] 37 #define Y y + dy[k] 38 inline int find_lose(int x, int y) { 39 if (x == n || y == n) return 2 * ((int) (x + y - 2) / 4); 40 return 2 * ((int) (x + y - 1) / 4); 41 } 42 43 inline int find_win(int x, int y) { 44 int k, res = 0; 45 for (k = 0; k < 4; ++k) 46 if (in(X, Y) && calc_sg(X, Y) == 0) 47 res = max(res, find_lose(X, Y)); 48 return res + 1; 49 } 50 51 inline int calc_lose(int x, int y, int i) { 52 int k, tmp = inf; 53 for (k = 0; k < 4; ++k) 54 if (in(X, Y) && calc_sg(X, Y) == 1 && find_win(X, Y) < tmp) { 55 tmp = find_win(X, Y); 56 ansx[i] = X, ansy[i] = Y; 57 } 58 } 59 60 inline int calc_win(int x, int y, int i) { 61 int k, tmp = -1; 62 for (k = 0; k < 4; ++k) 63 if (in(X, Y) && calc_sg(X, Y) == 0 && tmp < find_lose(X, Y)) { 64 tmp = find_lose(X, Y); 65 ansx[i] = X, ansy[i] = Y; 66 } 67 } 68 #undef X 69 #undef Y 70 71 int main() { 72 int i, x, y, tmp, max_lose = 0, max_win = 0; 73 k = read(), n = read(); 74 for (i = 1; i <= k; ++i) { 75 x = read(), y = read(); 76 tmp = calc_sg(x, y); 77 if (tmp == 0) { 78 max_lose = max(max_lose, find_lose(x, y)); 79 calc_lose(x, y, i); 80 continue; 81 } 82 max_win = max(max_win, find_win(x, y)); 83 calc_win(x, y, i); 84 } 85 if (max_lose > max_win) puts("NO"); else { 86 puts("YES"); 87 for (i = 1; i <= k; ++i) { 88 print(ansx[i]), putchar(' '); 89 print(ansy[i]), putchar('\n'); 90 } 91 } 92 return 0; 93 } 94 95 inline int read() { 96 int x = 0; 97 char ch = getchar(); 98 while (ch < '0' || '9' < ch) 99 ch = getchar(); 100 while ('0' <= ch && ch <= '9') { 101 x = x * 10 + ch - '0'; 102 ch = getchar(); 103 } 104 return x; 105 } 106 107 inline void print(const int &x) { 108 static int tot, pr[20], t; 109 t = x, tot = 0; 110 while (t) 111 pr[++tot] = t % 10, t /= 10; 112 if (!tot) putchar('0'); 113 while(tot) 114 putchar('0' + pr[tot--]); 115 }