【ZCMU1931】wjw的剪紙(dfs)
阿新 • • 發佈:2018-11-10
1931: wjw的剪紙
Time Limit: 4 Sec Memory Limit: 128 MB
Submit: 40 Solved: 13
[Submit][Status][Web Board]
Description
ly最近要生日了,wjw決定送一份禮物給這個傻孩子,考慮了一下禮物,發現貴的買不起,遠的不想去,麻煩的不想做...最後wjw決定剪一張好看的圖案給ly當作禮物,畢竟禮輕情意重嘛,情誼重就行了!
現在wjw手裡有一張正方形的彩紙,這張彩紙的邊長是n,由n*n個小正方形組成,現在wjw沿著小正方形的邊把這張彩紙剪成兩部分,為了美觀,他決定剪成形狀完全相同的兩部分...這時,wjw突發奇想,想知道到底能剪出多少種不同的圖案?但是wjw的智商不支援他回答自己的問題,於是他只能求助你,請你告訴他答案是多少.
//比如6*6的彩紙,以下是兩種剪法
Input
每組資料包含多組測試資料,每行一個正整數n(4<=n<=10)
Output
每行一個正整數表示答案
Sample Input
4
Sample Output
11
HINT
Source
【解題思路】
1.當n為奇數時,方格數肯定也是奇數,所以肯定不能平分,輸出0。
2.當n為偶數時,用dfs搜尋剪紙的軌跡,從中心點向4個方向搜尋,當碰到邊界時搜尋結束(自己畫個圖就知道啦~)。因為每個方向都是以中心點中心對稱的,所以會有重複情況,所以最終的ans/4。
3.因為n=10的情況跑的很慢,所以直接輸出即可。
【程式碼】
#include<bits/stdc++.h> using namespace std; int dirx[]={-1,0,0,1}; int diry[]={0,-1,1,0}; int vis[15][15],n,ans; void dfs(int x,int y) { if(x==0 || x==n || y==0 ||y==n) { ans++; return; } for(int i=0;i<4;i++) { int xx=x+dirx[i]; int yy=y+diry[i]; if(!vis[xx][yy]) { vis[xx][yy]=1; vis[n-xx][n-yy]=1; dfs(xx,yy); vis[xx][yy]=0; vis[n-xx][n-yy]=0; } } } int main() { while(~scanf("%d",&n)) { if(n%2)printf("0\n"); else if(n==4)printf("11\n"); else if(n==6)printf("509\n"); else if(n==8)printf("184525\n"); else printf("562070107\n"); /*ans=0; memset(vis,0,sizeof(vis)); vis[n/2][n/2]=1; dfs(n/2,n/2); printf("%d\n",ans/4);*/ } return 0; }