先说一说这个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 }
时间: 2024-10-12 20:06:27