题目链接
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

京公网安备 11010502036488号