第一次理解遞歸的含義,並且應用起來。如在這個題目裡,我一開始有好幾種想法,但都和自己手動模擬的不一樣。
大意:給出一個地圖,x表示牆,任何武器都不能穿過,.表示空地,在空地上可以建炮樓,每個炮樓都可以攻擊到東西南北方向上的炮樓,前提是不能有牆擋著,在各個炮樓不能相互攻擊的情況下,最多能建多少個炮樓。
---------------------------------------------------------
我們以測試數據
說明<==>就是等價的意思
接下來是完整的copy大神的代碼,後面附有自己為了弄明白dfs過程的調試數據,對自己的理解很有幫助!
/************************************************************************* File Name: 1045.cpp Author: yubo Mail: [email protected] Created Time: 2014年04月13日 星期日 22時26分40秒 學習重點: ************************************************************************/ #include同樣以2#include #include using namespace std; int ans;//標記個數 char map[10][10]; int n; int check(int r,int c) { int flag=1,i; for(i=r;i>=0;i--){//從[r][c]的上面開始查找 if(map[i][c]=='X') break; if(map[i][c]=='b'){ flag=0; break; } } for(i=c;i>=0;i--){//從[r][c]的左邊開始查找 if(map[r][i]=='X') break; if(map[r][i]=='b'){ flag=0; break; } } return flag; } void dfs(int pos,int sum) { int r=pos/n,c=pos%n;//計算所檢查的位置 // printf("pos=%d sum=%d r=%d c=%d \t",pos,sum,r,c); if(pos==n*n){//什麼意思呢,感覺pos永遠不會和n*n相等阿 if(sum>ans)//會的,這樣會把當前的活動點干死,執行這句dfs(pos+1,sum) ans=sum; return ; } if(map[r][c]=='.'){ if(check(r,c)==1){//符合題目要求的話 map[r][c]='b';//表示建立一個blockhouse dfs(pos+1,sum+1);//向下尋找,同時sum+1 map[r][c]='.';//這裡我就不懂了,為什麼要添加這一步哪 // printf("2r=%d 2pos=%d sum=%d\n",r,pos,sum);//有大用,這句話是回溯時恢復原來的狀態 } } dfs(pos+1,sum);//只是pos移動,其他沒有變化 } int main() { //freopen("in.txt","r",stdin); int i; while(scanf("%d",&n),n){ ans=0; memset(map,0,sizeof(map)); for(i=0;i >map[i]; dfs(0,0); printf("%d\n",ans); } }
..
..
為測試數據
並輸出部分數據你可能有更深刻的理解
/************************************************************************* File Name: 1045.cpp Author: yubo Mail: [email protected] Created Time: 2014年04月13日 星期日 22時26分40秒 學習重點: ************************************************************************/ #include中間過程數據;#include #include using namespace std; int ans;//標記個數 char map[10][10]; int n; int check(int r,int c) { int flag=1,i; for(i=r;i>=0;i--){//從[r][c]的上面開始查找 if(map[i][c]=='X') break; if(map[i][c]=='b'){ flag=0; break; } } for(i=c;i>=0;i--){//從[r][c]的左邊開始查找 if(map[r][i]=='X') break; if(map[r][i]=='b'){ flag=0; break; } } return flag; } void dfs(int pos,int sum) { int r=pos/n,c=pos%n;//計算所檢查的位置 printf("pos=%d sum=%d r=%d c=%d \t",pos,sum,r,c); if(pos==n*n){//什麼意思呢,感覺pos永遠不會和n*n相等阿 if(sum>ans)//會的,這樣會把當前的活動點干死,執行這句dfs(pos+1,sum) ans=sum; return ; } if(map[r][c]=='.'){ if(check(r,c)==1){//符合題目要求的話 map[r][c]='b';//表示建立一個blockhouse dfs(pos+1,sum+1);//向下尋找,同時sum+1 map[r][c]='.';//這裡我就不懂了,為什麼要添加這一步哪 printf("2r=%d 2pos=%d sum=%d\n",r,pos,sum);//有大用,這句話是回溯時恢復原來的狀態 } } dfs(pos+1,sum);//只是pos移動,其他沒有變化 //printf("pos=%d sum=%d\t",r,c); } int main() { freopen("in.txt","r",stdin); int i; while(scanf("%d",&n),n){ ans=0; memset(map,0,sizeof(map)); for(i=0;i >map[i]; dfs(0,0); printf("%d\n",ans); } }
pos=0 sum=0 r=0 c=0 pos=1 sum=1 r=0 c=1 pos=2 sum=1 r=1 c=0 pos=3 sum=1 r=1 c=1 pos=4 sum=2 r=2 c=0 2r=1 2pos=3 sum=1 pos=4 sum=1 r=2 c=0 2r=0 2pos=0 sum=0 pos=1 sum=0 r=0 c=1 pos=2 sum=1 r=1 c=0 pos=3 sum=2 r=1 c=1 pos=4 sum=2 r=2 c=0 2r=1 2pos=2 sum=1 pos=3 sum=1 r=1 c=1 pos=4 sum=1 r=2 c=0 2r=0 2pos=1 sum=0 pos=2 sum=0 r=1 c=0 pos=3 sum=1 r=1 c=1 pos=4 sum=1 r=2 c=0 2r=1 2pos=2 sum=0 pos=3 sum=0 r=1 c=1 pos=4 sum=1 r=2 c=0 2r=1 2pos=3 sum=0 pos=4 sum=0 r=2 c=0 2