1. DFS遍历
2.问题
2.1 POJ 2488
题目大意:有一个矩形棋盘,骑士的移动遵循一个规则——向一个方向走两格、再垂直于这个方向走一格,(有点像中国象棋的马走“日”字),问骑士可不可能不重复地走遍棋盘的每一个方块。
这是一个“骑士游历”的问题。骑士最多有8种方向移动,遍历所有的移动可能。
源代码:
2488 | Accepted | 160K | 16MS | C | 1030B | 2013-10-11 17:21:57 |
#include "stdio.h"
#include "string.h"
typedef struct square
{
int x,y;
}Square;
int p,q,possible,visit[9][9];
int move[8][2]={{-1, -2}, {1, -2}, {-2, -1}, {2, -1}, {-2, 1}, {2, 1}, {-1, 2}, {1, 2}};
Square path[26];
void dfs(int depth,int x,int y)
{
int i,newx,newy;
visit[x][y]=1;
path[depth].x=x; path[depth].y=y;
if(depth==p*q-1) //递归结束
{
possible=1;
for(i=0;i<p*q;i++)
printf("%c%d",path[i].y+'A',path[i].x+1);
printf("\n");
return;
}
for(i=0;i<8;i++)
{
newx=x+move[i][0]; newy=y+move[i][1];
if(newx>=0&&newx<p&&newy>=0&&newy<q&&!visit[newx][newy]&&!possible)
{
dfs(depth+1,newx,newy);
visit[newx][newy]=0; //回溯
}
}
}
int main()
{
int i,test_cases;
scanf("%d",&test_cases);
for(i=1;i<=test_cases;i++)
{
scanf("%d%d",&p,&q);
printf("Scenario #%d:\n",i);
memset(visit,0,sizeof(visit));
possible=0;
dfs(0,0,0);
if(!possible)
printf("impossible\n");
printf("\n");
}
return 0;
}
2.2 POJ 1321
本题是一般化的“八皇后问题”:棋盘形状不规则,只需放k个棋子,且k<=n。
用visit[ ]记录每列的访问情况,访问k个点之后,递归结束。
源代码:
1321 | Accepted | 160K | 47MS | C | 602B | 2013-10-11 19:12:13 |
#include "stdio.h"
#include "string.h"
int n,k,count,visit[8];
char matrix[8][8];
void dfs(int depth,int x)
{
int i,j;
if(depth==k)
{
count++;
return;
}
if(x==n) return; //剪枝
for(i=x;i<n;i++)
for(j=0;j<n;j++)
if(matrix[i][j]=='#'&&!visit[j])
{
visit[j]=1;
dfs(depth+1,i+1);
visit[j]=0; //回溯
}
}
int main()
{
int i;
while(scanf("%d%d",&n,&k),n!=-1)
{
for(i=0;i<n;i++)
scanf("%s",matrix[i]);
memset(visit,0,sizeof(visit));
count=0;
dfs(0,0);
printf("%d\n",count);
}
return 0;
}