题目链接
https://ac.nowcoder.com/acm/contest/8564/C
解题思路
来自官方题解:
首先可以发现当 n 为奇数时必然无解
对于 n 是偶数,我们给出两种构造方案
1:以一个 2×2×1 的方块为基本单位,黑白相间摆满整个立方体即可
2:从外向内一圈一圈黑白染色,上下两层颜色相反即可
AC代码1
//对应方案一 #include<bits/stdc++.h> using namespace std; int n; int F;//控制每一层开始的颜色 int f;//控制每一层中每两行颜色的交换 int out;//控制每一层每一个小正方区域(即4个小正方体组成的)颜色的交换 int main() { cin>>n; if(n&1) cout<<-1<<endl;//n为奇数 else { for(int i=1;i<=n;i++,F^=1)//F取反一下 { f=F;//每层的颜色变换要从F开始 for(int j=1;j<=n;j++) { if(j&1) f^=1;//奇数行时,控制每两行颜色的f取反 out=f;//设置开始的小正方区域颜色 for(int k=1;k<=n;k++) { if(k&1) out^=1;//奇数列时,小正方区域的颜色变换 cout<<out<<(k==n?'\n':' '); } } } } return 0; }
AC代码2
//对应方案二 #include<bits/stdc++.h> using namespace std; const int N=100; int coo[N][N];//点(i,j)所处圈数 int num;//圈数 int l,r;//下有 int row;//下有 int n; int F;//控制每一层最外圈的颜色 int f;//控制每一层每一圈的颜色 int main() { cin>>n; if(n&1) cout<<-1<<endl; else { //求点(i,j)所处的圈数,从外到内增加,圈数从1开始 for(int i=1;i<=n;i++)//遍历行 { row=min(n-i+1,i);//这行的点最多处于第row圈 num=1;//每行的最外圈一定是第一圈,向内依次增加,直至=row l=1;r=n;//l,r为双指针,分别指向本行的第一列和最后一列 while(num<row)//如果当前循环到的圈数 < 最大圈数 { coo[i][l]=coo[i][r]=num;//此行l列与此行r列都在第num圈 l++,r--;//往内圈走 num++;//圈数++ } while(l<r)//圈数最多赋值到row,不能再增加了,所以此行l~r之间的全部赋值为row { coo[i][l]=coo[i][r]=row; l++,r--; } } /* //-------test------- for(int i=1;i<=n;i++,cout<<endl) for(int j=1;j<=n;j++) cout<<coo[i][j]<<' '; */ for(int i=1;i<=n;i++,F^=1,f=F) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) { cout<<(f^(coo[j][k]&1))<<(k==n?'\n':' ');//先取此点所处圈数的最低位二进制,再与f异或 } } return 0; }
总结
没想到,不知道为什么奇数不行,也没想到这俩方案。
根据思路实现也费了很大劲了。
WTCL