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; }
本题是一般化的“八皇后问题”:棋盘形状不规则,只需放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; }