BZOJ1393 [Ceoi2008]knights

题意。。。上ceoi官网看吧。。。

首先打一下sg函数发现必胜态和必败态的分布位置是有规律的

于是我们只要知道最长步数的必胜态和最长步数的必败态哪个更长就可以了

然后再打一下步数的表。。。发现必败态的最长步数非常好确定,那么必胜态的步数搜一下就可以了!

  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('
');
 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 }
View Code
By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
原文地址:https://www.cnblogs.com/rausen/p/4352029.html