第一次理解遞歸的含義,並且應用起來。如在這個題目裡,我一開始有好幾種想法,但都和自己手動模擬的不一樣。
大意:給出一個地圖,x表示牆,任何武器都不能穿過,.表示空地,在空地上可以建炮樓,每個炮樓都可以攻擊到東西南北方向上的炮樓,前提是不能有牆擋著,在各個炮樓不能相互攻擊的情況下,最多能建多少個炮樓。
---------------------------------------------------------
我們以測試數據
說明<==>就是等價的意思
接下來是完整的copy大神的代碼,後面附有自己為了弄明白dfs過程的調試數據,對自己的理解很有幫助!
/*************************************************************************
File Name: 1045.cpp
Author: yubo
Mail: yuzibode@126.com
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移動,其他沒有變化
}
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);
}
}
同樣以2
..
..
為測試數據
並輸出部分數據你可能有更深刻的理解
/*************************************************************************
File Name: 1045.cpp
Author: yubo
Mail: yuzibode@126.com
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