先说一说这个OJ:貌似是11区某大学ACM的OJ,叫AIZU ONLINE JUDGE,貌似还可以看到部分犇的代码。。。跪跪跪

然后知道这个OJ是某场比赛安利的= =

接下来将做法:

首先我们可以发现每个点周围两种颜色的个数都是2...(不要问我为什么)

然后可以发现,构成图形是由2 * 2的同色的地砖或者围成一圈的同色地砖且每边的长度都是偶数,详见样例(不要问我为什么,因为很重要所以说两遍)

接着可以发现,如果第一行的状态确定了,整个解就确定了,而且第一行的状态可以做到和k一一对应(不要问我为什么,因为很重要所以说三遍)

然后就可以直接进行构造了。。。

对于一个点(x, y),它上面的点(x, y - 1)的周围另外三个点的颜色都已经确定了,故也可以将它的颜色确定

 

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 100;
 7 const int dx[] = {1, -1, 0, 0};
 8 const int dy[] = {0, 0, 1, -1};
 9 
10 int n;
11 ll K;
12 int mp[N][N];
13 
14 inline bool out (int x) {
15     return x <= 0 || x > n;
16 }
17 
18 #define X i + dx[k]
19 #define Y j + dy[k]
20 int main() {
21     int i, j, k, cnt;
22     while (scanf("%d%lld", &n, &K), n) {
23         --K;
24         if (K >= (1ll << (n / 2)) || (n & 1)) {
25             puts("No");
26             putchar('\n');
27             continue;
28         }
29         memset(mp, -1, sizeof(mp));
30         for (i = 1; i <= n; ++i)
31             mp[1][i] = ((K >> (n - i >> 1)) & 1);
32         for (i = 1; i < n; ++i)
33             for (j = 1; j <= n; ++j) {
34                 for (k = cnt = 0; k < 4; ++k) {
35                     if (out(X) || out(Y)) continue;
36                     if (mp[X][Y] == mp[i][j]) ++cnt;
37                 }
38                 if (cnt == 2) mp[i + 1][j] = !mp[i][j];
39                 else mp[i + 1][j] = mp[i][j];
40             }
41         for (i = 1; i <= n; ++i) {
42             for (j = 1; j <= n; ++j)
43                 putchar(mp[i][j] ? 'E' : '.');
44             putchar('\n');
45         }
46         putchar('\n');
47     }
48     return 0;
49 }
View Code

 

posted on 2015-03-13 16:00  Xs酱~  阅读(264)  评论(0编辑  收藏  举报