小明要把一根木头切成两段,然后拼接成一个直角。
如下图所示,他把中间部分分成了 n × n 的小正方形,他标记了每个小正方形属于左边还是右边。然后沿两边的分界线将木头切断,将右边旋转向上后拼接在一起。
要求每个小正方形都正好属于左边或右边,而且同一边的必须是连通的。
在拼接时,拼接的部位必须保持在原来大正方形里面。
请问,对于 7 × 7 的小正方形,有多少种合法的划分小正方形的方式。
结果2444 不知道对不对
最开始看到这个题的时候也是毫无思路,曾试着从1 * 1 开始数,看看能不不能找到规律,有发现但没啥用。然后网上也没有关于这道题的任何解答,还是尝试着想了想,利用DFS。
首先先说一下我后来的思路。先以2 * 2为例
我先以左下角和右上角为轴,这样的话,右下方画出的分割线对称之后就是整体的。我发现的规律就是从这条对角线上的每个点出发,向四个方向搜索,如果条件是对的就可以到下个点继续,直到到了最右边的竖线上的任意一点,此时为一种情况,并返回。
4 * 4 和后面是同理的。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int a[8][8];
int num = 0;
int b[4][2] = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
void tc(){
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
a[i][j] = 0;
}
}
}
void DFS(int x, int y, int bx, int by){
a[x][y] = 1;
if(x == 7){
// cout << x << " " << y << endl;
num++;
a[x][y] = 0;
return;
}
int tx = 0, ty = 0;
for(int i = 0; i < 4; i++){
tx = x + b[i][0];
ty = y + b[i][1];
if((y == 0 && ( i == 2 || i == 3 )) || (tx < 0 || ty < 0) || a[tx][ty] == 1){
if(i == 3){
a[x][y] = 0;
}
continue;
}
if((tx == ty || tx < ty) || (tx == bx && ty == by)){
if(i == 3)
a[x][y] = 0;
continue;
}
else{
a[x][y] = 1;
DFS(tx, ty, x, y);
if(i == 3)
a[x][y] = 0;
continue;
}
}
}
int main(){
for(int i = 0; i <= 7; i++){
tc();
DFS(i, i, -2, -2);
}
cout << num;
return 0;
}
只不过方格越多情况也就越多最基本的是,你在这个点搜索的时候,不能再回到你来的那方向。在最下面那条线上的时候,不能再向上搜索,等等。
代码应该不是最完善的,有想法的朋友可以交流一下。