深度搜索,但是要注意搜索的方式:
本文给出两份代码,一份是AC代码,一份是超时的,你们感受下。
从第一行开始,对于每一行,搜索整行,如果有‘#’,标记,然后,则搜索下一行。
AC代码:
/*POJ1321 作者:陈佳润 2013-04-11 */ #include<iostream> #include<stdio.h> using namespace std; int line[9]; int map[9][9]; int n;//棋盘大小 int m;//摆放棋子的数目 int allsum;//方案数 void DFS(int row,int sum){ if(sum==m){//如果满足要求,增加数量1,退出 allsum++; return; } if(row>n) //防止越界 return; for(int i=1;i<=n;i++){//对于行row,穷举每一列 if(map[row][i]&&line[i]){ line[i]=0; DFS(row+1,sum+1); line[i]=1; } } DFS(row+1,sum); } int main(){ int i,j; char c; //freopen("1.txt","r",stdin); while(cin>>n>>m&&(n!=-1&&m!=-1)){ getchar(); for(i=1;i<=n;i++){//读取,并转化成01矩阵 for(j=1;j<=n;j++){ scanf("%c",&c); if(c=='#') map[i][j]=1; else map[i][j]=0; } getchar(); } //初始化 allsum=0; for(i=1;i<=n;i++) line[i]=1; //深搜 DFS(1,0); cout<<allsum<<endl; } return 0; }
超时的代码:
/*POJ1321 作者:陈佳润 2013-04-11 */ #include<iostream> #include<stdio.h> using namespace std; int n,m; char map[9][9]; bool flag[9][9]; int row[9],line[9];//信号量 int allsum; void BFS(int i,int j,int sum){ if(i==0||i>n||j==0||j>n)//越界 return; if(flag[i][j]==false)//已经走过 return; if(map[i][j]=='#'&&row[i]==0&&line[j]==0){//如果该位置可以 flag[i][j]=false; row[i]++; line[j]++; sum++; if(sum==m){ allsum++; sum--; row[i]--; line[j]--; } BFS(i,j+1,sum); BFS(i,j-1,sum); BFS(i+1,j,sum); BFS(i-1,j,sum); flag[i][j]=true; row[i]--; line[j]--; }else{//空白位置 flag[i][j]=false; BFS(i,j+1,sum); BFS(i,j-1,sum); BFS(i+1,j,sum); BFS(i-1,j,sum); flag[i][j]=true; } } int main(){ int i,j; //freopen("1.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF&&(n!=-1||m!=-1)){ getchar(); for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ scanf("%c",&map[i][j]); } getchar(); } for(i=1;i<=n;i++){//初始化 row[i]=0; line[i]=0; for(j=1;j<=n;j++) flag[i][j]=true; } allsum=0; BFS(1,1,0); printf("%d\n",allsum); } return 0; }