藍橋杯每日一題1.6 2017省賽A組4.方格分割[DFS]
題目描述
6x6的方格,沿著格子的邊線剪開成兩部分。要求這兩部分的形狀完全相同。如圖就是可行的分割法。
試計算:包括這3種分法在內,一共有多少種不同的分割方法。注意:旋轉對稱的屬於同一種分割法。
輸出
輸出一個整數表示答案
https://blog.csdn.net/weixin_43914593/article/details/112257103
✬✬✬✬✬如何從分割方格來聯想到DFS呢?✬✬✬✬✬
highlight:
1.由於旋轉對稱的屬於同一種分割法,得到的結果要/4
2.由題意,這一條切割線必定經過圖的中心點,那麼我們一旦確定了半條到達邊界的分割線,就能根據這半條對稱畫出另外半條。(所以就可以從中心的點往外搜)
3.在搜尋過程中需要注意的是,我們搜尋出的半條分割線不能同時經過關於中心對稱的兩個點,所以在標記時,需要將對稱的點也標上。(vis[x][y]=true的同時vis[6-x][6-y]=true)
4.向右、向左、向上、向下,四個方向DFS即可。
int X[]={0,-1,1,0,0};
int Y[]={0,0,0,-1,1};
x+=X[i];
y+=Y[i];
mistakes:
1.在for迴圈裡面進行遞迴
2.走完一步之後再來詢問是否訪問過這個點
for(int i = 1 ; i <= 4 ; i++){ //上下左右四個方向
x += X[i]; y += Y[i]; //走一步
if(!vis[x][y]){ // 若該點未訪問則繼續深搜
vis[x][y] = true; // 當前的點標註為已訪問
vis[6 - x][6 - y] = true;
dfs(x, y); // 繼續深搜
vis[6 - x][6 - y] = false;
vis[x][y] = false;
}
x -= X[i]; y -= Y[i];
}
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<set> #include<queue> #include<stack> #include<map> using namespace std; typedef long long ll; const int maxn = 110000; int X[]={0,-1,1,0,0}; int Y[]={0,0,0,-1,1}; bool vis[10][10]; int ans=0; void dfs(int x,int y) { if(x==0||x==6||y==0||y==6) { ans++; return ; } for(int i=1;i<=4;i++) { x+=X[i]; y+=Y[i]; if(!vis[x][y]) { vis[x][y]=true; vis[6-x][6-y]=true; dfs(x,y); vis[6-x][6-y]=false; vis[x][y]=false; } x-=X[i]; y-=Y[i]; } } int main() { vis[3][3]=true; dfs(3,3); cout<<ans/4; return 0; }