积木 \operatorname{积木} 积木
题目链接: nowcoder 213757 \operatorname{nowcoder\ 213757} nowcoder 213757
到牛客看:
题目
scimoon 有一个包含了 n × n × n n\times n\times n n×n×n 个小方块的立方体(比如,三阶魔方就是一个包含了 3 × 3 × 3 3\times 3\times 3 3×3×3 个小方块的立方体)
我们称:两个方块是相邻的当且仅当他们有一个公共的面
现在 scimoon 想要给每个小方块上黑白两色之一,使得:
与一个黑色方块相邻的方块恰好有两个是黑色的
与一个白色方块相邻的方块恰好有两个是白色的
由于这个问题非常困难,所以 scimoon 想让聪明的你解决这个问题
输入
一个整数 n n n,意义与题目描述中一致
输出
如果没有解,请输出 − 1 -1 −1,否则,请你输出这个立方体
输出方式为:自底向上输出 n n n 个 n × n n\times n n×n 的矩阵,第 i i i 个矩阵中的数 ( j , k ) (j,k) (j,k) 代表第 i i i 层,第 j j j 行,第 k k k 列的方块的颜色
一个方块是黑色的请输出 0 0 0,否则输出 1 1 1
样例输入1
2
样例输出1
1 1
0 0
1 1
0 0
样例输入2
1
样例输出2
-1
数据范围
1 ≤ n ≤ 100 1\leq n\leq 100 1≤n≤100
思路
这道题是一道思维题。
我们可以想到有两种情况。
第一:
形如这样:
1111 0000 1111 0000 1111
1001 0110 1001 0110 1001
1001 0110 1001 0110 1001
1111 0000 1111 0000 1111
因为题目要一个方块周围只有两个方块跟它颜色相同,那所有都要满足这样,那其实可以说就是一个连在一起的相同颜色的就会是一个链子(或者一个环)
就是把每个方块都连一条边向它旁边颜色相同的边,那要只会每个方块都之连向两条边,就是要形成许多的环。
那就可以想到对于每一个平面,先在最外面围一层同一个颜色(假设为白色),然后里面一层就围黑色,然后再里面一层又围白色,以此类推。
然后在下一个平面就是上一个平面全部反过来。(这样不同平面之间就不会连边)、
那可以看出如果边长是偶数,就围不成。因为最后会剩下一个点单独存在,就像这样:
111
101
111
第二:
我们可以根据上面想到,要形成最小的链子,就是这样的结构:
11
11
或者这个:
00
00
(就是 1 × 2 × 2 1\times\ 2\times 2 1× 2×2 的方块)
那我们就错开摆放,也是合法的。
就像这样:
1100 0011 1100 0011
1100 0011 1100 0011
0011 1100 0011 1100
0011 1100 0011 1100
那我们也同样可以得出当边长是奇数的时候围不成。
代码
#include<cstdio>
using namespace std;
int n, a[101][101];
int main() {
scanf("%d", &n);
if (n & 1) {
printf("-1");
return 0;
}
for (int i = 1; i <= n / 2; i += 2) {//先排出第一层
for (int j = i; j <= n - i + 1; j++) {
a[i][j] = 1;
a[j][i] = 1;
a[n - i + 1][j] = 1;
a[j][n - i + 1] = 1;
}
}
for (int i = 1; i <= n; i++)//输出
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++)
printf("%d ", a[j][k] ^ (i % 2));
printf("\n");
}
return 0;
}