链接:第三次组队赛
//这一次是搜索全场.......哎~感觉BFS还行,但DFS不是很懂啊.............= =
A.A Knight's Journey
据说是很经典但也是很水的DFS题目~
题意:在一个p*q的棋盘上,一个knight要环游棋盘 ,每个点只走一遍,要历遍所有的点,问是否可能,若不可以则输出impossible,反之输出坐标。
注:在题目中要求按字典树输出,故要注意坐标点~按下图的序号走,则从(A,1)开始历遍,第一次成功的就是按字典树排列的点~
代码:
1 #include2 #include 3 #include 4 using namespace std; 5 6 const int add[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}}; 7 int a[27][27],p,q,judge,step; 8 9 class K 10 { 11 public: 12 int x,y; 13 }knight[100]; 14 15 void DFS(int x,int y) 16 { 17 if(judge) return; 18 int i,hx,hy; 19 knight[step].x=x; 20 knight[step].y=y; 21 step++; 22 if(step==p*q) 23 {judge=1;return;} 24 a[x][y]=1; 25 for(i=0;i<8;i++) 26 { 27 hx=x+add[i][1]; 28 hy=y+add[i][0]; 29 if(hx>=0 && hx =0 && hy
a[hx][hy]) 30 { 31 DFS(hx,hy); 32 step--; 33 } 34 } 35 a[x][y]=0; 36 return; 37 } 38 39 int main() 40 { 41 int t,i,j,k=1; 42 scanf("%d",&t); 43 while(t--) 44 { 45 scanf("%d%d",&p,&q); 46 printf("Scenario #%d:\n",k); 47 k++; 48 if(p*q<1 || p*q>26) {printf("impossible\n\n");continue;} 49 memset(a,0,sizeof(a)); 50 memset(knight,0,sizeof(knight)); 51 judge=0; 52 step=0; 53 DFS(0,0); 54 if(judge) 55 { 56 for(i=0;i) 57 printf("%c%d",knight[i].y+65,knight[i].x+1); 58 printf("\n\n"); 59 } 60 else 61 printf("impossible\n\n"); 62 } 63 return 0; 64 }
B.Avoid The Lakes
很简单~~~BFS
代码:
1 #include2 #include 3 #include 4 using namespace std; 5 6 int a[100][100],maxx,X,Y,G,number; 7 int add[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; 8 9 class O 10 { 11 public: 12 int x,y; 13 }q[10025]; 14 15 void bfs(int x,int y) 16 { 17 int f=0,r=1,hx,hy,i; 18 memset(q,0,sizeof(q)); 19 q[0].x=x; 20 q[0].y=y; 21 a[x][y]=0; 22 number=1; 23 while(f<=r) 24 { 25 for(i=0;i<4;i++) 26 { 27 hx=q[f].x+add[i][1]; 28 hy=q[f].y+add[i][0]; 29 if(hx>=0 && hx =0 && hy a[hx][hy]) 30 { 31 a[hx][hy]=0; 32 q[r].x=hx; 33 q[r++].y=hy; 34 number++; 35 } 36 } 37 f++; 38 } 39 if(number>maxx) maxx=number; 40 return; 41 } 42 43 int main() 44 { 45 while(scanf("%d%d%d",&X,&Y,&G)!=EOF) 46 { 47 int i,j,k; 48 memset(a,0,sizeof(a)); 49 for(k=0;k ) 50 { 51 scanf("%d%d",&i,&j); 52 a[i-1][j-1]=1; 53 } 54 maxx=0; 55 for(i=0;i ) 56 for(j=0;j ) 57 { 58 if(a[i][j]) bfs(i,j); 59 } 60 printf("%d\n",maxx); 61 } 62 return 0; 63 }
C.Dungeon Master
比较简单~是一道三维的BFS题目~只要注意三维字符串的输入即可,其它的跟二维相同~
代码:
1 #include2 #include 3 #include 4 using namespace std; 5 6 int number,Z,X,Y,x1,y1,z1,x2,y2,z2; 7 const int add[6][3]={{0,1,0},{0,-1,0},{1,0,0},{-1,0,0},{0,0,1},{0,0,-1}}; 8 char a[30][30][30]; 9 10 class K 11 { 12 public: 13 int x,y,z,step; 14 }k[1000000]; 15 16 void bfs(int z,int x,int y) 17 { 18 int f=0,r=1,i,hx,hy,hz; 19 k[0].x=x; 20 k[0].y=y; 21 k[0].z=z; 22 k[0].step=0; 23 a[z][x][y]='#'; 24 k[1000000]={0}; 25 while(f<r) 26 { 27 28 for(i=0;i<6;i++) 29 { 30 hx=k[f].x+add[i][0]; 31 hy=k[f].y+add[i][1]; 32 hz=k[f].z+add[i][2]; 33 34 if(hx>=0 && hx =0 && hy =0 && hz '.' ||a[hz][hx][hy]=='E') ) 35 { 36 if(a[hz][hx][hy]=='E') 37 {number=k[f].step+1; return;} 38 k[r].x=hx; 39 k[r].y=hy; 40 k[r].z=hz; 41 k[r++].step=k[f].step+1; 42 a[hz][hx][hy]='#'; 43 } 44 } 45 f++; 46 } 47 return; 48 } 49 50 int main() 51 { 52 while(scanf("%d%d%d",&Z,&X,&Y)&&Z&&Y&&X) 53 { 54 int i,j,k; 55 memset(a,0,sizeof(a)); 56 for(i=0;i ) //三维字符串输入 57 { 58 for(j=0;j ) 59 scanf("%s",a[i][j]); 60 } 61 62 for(i=0;i ) 63 for(j=0;j ) 64 for(k=0;k ) 65 { 66 if(a[i][j][k]=='S') 67 { 68 x1=j; 69 y1=k; 70 z1=i; 71 } 72 if(a[i][j][k]=='E') 73 74 { 75 x2=j; 76 y2=k; 77 z2=i; 78 } 79 } 80 number=0; 81 bfs(z1,x1,y1); 82 if(number==0) 83 printf("Trapped!\n"); 84 else 85 printf("Escaped in %d minute(s).\n",number); 86 } 87 return 0; 88 }
D.Sum It Up
DFS~
代码:
1 #include2 #include 3 #include 4 using namespace std; 5 6 int N,t,judge,a[10000],k[10000]; 7 8 void DFS(int sum,int x,int step) 9 { 10 int i; 11 if(sum>N) return; 12 if(sum==N) 13 { 14 printf("%d",k[0]); 15 for(i=1;i ) 16 printf("+%d",k[i]); 17 printf("\n"); 18 judge=true; 19 return; 20 } 21 int last=-1; 22 for(i=x;i ) 23 { 24 if(sum+a[i]>N) continue; 25 if(a[i]!=last) //重点!!!!last代表跳出的数,避免出现相同式子!! 26 { 27 last=k[step]=a[i]; 28 DFS(sum+a[i],i+1,step+1); 29 } 30 } 31 } 32 33 int main() 34 { 35 while(~scanf("%d%d",&N,&t),N,t) 36 { 37 int i; 38 memset(a,0,sizeof(a)); 39 memset(k,0,sizeof(k)); 40 for(i=0;i ) 41 scanf("%d",&a[i]); 42 printf("Sums of %d:\n",N); 43 judge=false; 44 DFS(0,0,0); 45 if(!judge) printf("NONE\n"); 46 } 47 return 0; 48 }
E.N皇后问题
由于数据很小,SO.........采用枚举水过的代码:
1 #include2 #include 3 using namespace std; 4 int main() 5 { 6 int i,sum; 7 while(~scanf("%d",&i),i) 8 { 9 if(i==1) 10 sum=1; 11 if(i==2 || i==3) 12 sum=0; 13 if(i==4) 14 sum=2; 15 if(i==5) 16 sum=10; 17 if(i==6) 18 sum=4; 19 if(i==7) 20 sum=40; 21 if(i==8) 22 sum=92; 23 if(i==9) 24 sum=352; 25 if(i==10) 26 sum=724; 27 cout< endl; 28 } 29 return 0; 30 }
正解:
代码:
1 #include2 #include 3 #include 4 using namespace std; 5 6 #define N 15 7 int n; 8 int sum; 9 int x[N],b[N]; 10 11 12 int place(int k) 13 { 14 int i; 15 for(i=1;i ) 16 if(abs(k-i)==abs(x[k]-x[i]) || x[k] == x[i]) 17 return 0; 18 return 1; 19 } 20 21 22 int queen(int t) 23 { 24 if(t>n && n>0) //当放置的皇后超过n时,可行解个数加1,此时n必须大于0 25 sum++; 26 else 27 for(int i=1;i<=n;i++) 28 { 29 x[t] = i; //标明第t个皇后放在第i列 30 if(place(t)) //如果可以放在某一位置,则继续放下一皇后 31 queen(t+1); 32 } 33 return sum; 34 } 35 36 int main() 37 { 38 int t,i; 39 for(i=1;i<=10;i++) 40 { 41 sum=0; 42 n=i; 43 b[i]=queen(1); 44 } 45 while(scanf("%d",&n),n) 46 { 47 printf("%d\n",b[n]); 48 } 49 return 0; 50 }
源代码:http://blog.sina.com.cn/s/blog_696187fd0100p5ri.html
在此基础上做了一小部分改动.........
F.Basic
是变形的N皇后问题~
在每一个能放棋子的点,作为第一个放棋子的点,看能放多少棋子,输出最多能放的棋子数~
代码:
1 #include2 #include 3 #include 4 using namespace std; 5 6 int n,number; 7 char a[10][10]; 8 9 int judge(int x,int y) //判断该点能否放棋子,在遇到X前,该点所对应的横排和竖排是否有0点,若有则不能放棋子 10 { 11 int i; 12 for(i=x+1;i<=n && a[i][y]!='X';i++) 13 if(a[i][y]=='0') return false; 14 for(i=x-1;i>=1 && a[i][y]!='X';i--) 15 if(a[i][y]=='0') return false; 16 for(i=y+1;i<=n && a[x][i]!='X';i++) 17 if(a[x][i]=='0') return false; 18 for(i=y-1;i>=1 && a[x][i]!='x';i--) 19 if(a[x][i]=='0') return false; 20 return true; 21 } 22 23 void DFS(int x,int y,int step) 24 { 25 int i,j; 26 for(i=1;i<=n;i++) 27 for(j=1;j<=n;j++) 28 if(a[i][j]=='.' && judge(i,j)) 29 { 30 a[i][j]='0'; 31 DFS(i,j,step+1); 32 a[i][j]='.'; 33 } 34 if(number step; 35 } 36 37 int main() 38 { 39 while(scanf("%d",&n),n) 40 { 41 memset(a,0,sizeof(a)); 42 for(int i=1;i<=n;i++) 43 scanf("%s",a[i]+1); 44 number=0; 45 DFS(1,1,0); 46 printf("%d\n",number); 47 } 48 return 0; 49 }
G.Asteroids!
与第三题很相似,也是三维的BFS~
代码如下:
1 #include2 #include 3 #include 4 using namespace std; 5 6 int number,quan,N,x1,y1,z1,x2,y2,z2; 7 const int add[6][3]={{0,1,0},{0,-1,0},{1,0,0},{-1,0,0},{0,0,1},{0,0,-1}}; 8 char a[30][30][30]; 9 10 class K 11 { 12 public: 13 int x,y,z,step; 14 }k[1000000]; 15 16 void bfs(int z,int x,int y) 17 { 18 int f=0,r=1,i,hx,hy,hz; 19 memset(k,0,sizeof(k)); 20 k[0].x=x; 21 k[0].y=y; 22 k[0].z=z; 23 k[0].step=0; 24 a[z][x][y]='X'; 25 while(f<r) 26 { 27 for(i=0;i<6;i++) 28 { 29 hx=k[f].x+add[i][0]; 30 hy=k[f].y+add[i][1]; 31 hz=k[f].z+add[i][2]; 32 33 if(hx>=0 && hx =0 && hy =0 && hz 'O') 34 { 35 if(hz==z2 && hx==x2 && hy==y2) 36 {number=k[f].step+1; return;} 37 k[r].x=hx; 38 k[r].y=hy; 39 k[r].z=hz; 40 k[r++].step=k[f].step+1; 41 a[hz][hx][hy]='X'; 42 } 43 } 44 f++; 45 } 46 return; 47 } 48 49 int main() 50 { 51 char w[4],q[10]; 52 while(~scanf("%s",q)) 53 { 54 scanf("%d",&N); 55 int i,j,k; 56 memset(a,0,sizeof(a)); 57 for(i=0;i ) 58 { 59 for(j=0;j ) 60 scanf("%s",a[i][j]); 61 } 62 scanf("%d%d%d",&z1,&x1,&y1); 63 scanf("%d%d%d",&z2,&x2,&y2); 64 scanf("%s",w); 65 quan=0; 66 if(a[z2][x2][y2]=='O') quan++; 67 if(a[z2][x2][y2]=='X') {a[z2][x2][y2]='O';quan--;} 68 number=0; 69 if(z1==z2 && x1==x2 && y1==y2) {printf("%d 0\n",quan);continue;} 70 bfs(z1,x1,y1); 71 if(number==0) 72 printf("NO ROUTE\n"); 73 else 74 printf("%d %d\n",number+quan,number); 75 } 76 return 0; 77 }