T1:棋盘问题 POJ-1321 POJ-1321

分析:本题给出棋盘分布以及落子数目,让我们求出在棋子不同行不同列摆放的情况下,有几种落子方式。

本题我们利用DFS算法,编写一个递归函数。从第一行第一列的位置开始在列内扫描,如果找到合适位置就落子,然后把这一列标记,表示这一列不能够再次落子。

这样之后,将前面落子位置往右往下移一位,在这个新位置调用递归函数。当棋子全部用完,则方案数加1。

PS:要注意理解整个过程的深度优先搜索思路,这样子有利于理解代码。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn=10;
 5 char chessboard[maxn][maxn];
 6 bool visit[maxn];//用于标记列是否还能够放下棋子 
 7 int ans;//表示方案数
 8 int k;//表示棋子数目
 9 int n;//表示棋盘的大小 
10 int DFS(int row,int nums_of_chess){//row代表当前行,nums_of_chess代表已经使用的棋子数目 
11     if(nums_of_chess==k){
12         ans++;
13         return 0;
14     }
15     for(int i=row;i<n;i++)
16         for(int j=0;j<n;j++)
17             if(!visit[j]&&chessboard[i][j]=='#'){//如果这一列没有被标记,而且这个位置是棋盘位置 
18                 visit[j]=true;//将这一列标记 
19                 DFS(i+1,nums_of_chess+1);//递归调用函数 
20                 visit[j]=false;//此处函数已经返回,应该将列标记还原,这样子才能够不影响下一行的过程判定
21             }
22     return 0;
23 }
24 int main(){ 
25     while(cin>>n>>k){
26         if(n==-1&&k==-1) break;
27         memset(visit,false,sizeof(visit));
28         for(int i=0;i<n;i++)
29         for(int j=0;j<n;j++)
30             cin>>chessboard[i][j];
31         ans=0;
32         DFS(0,0);
33         cout<<ans<<endl;
34     }
35     return 0;
36 }

 

T2:迷宫问题 POJ-3984 POJ-3984

问题分析:这是一个迷宫问题,可以理解为最短路线与记录移动路径相结合的问题。最短路线问题一般利用BFS,广度优先搜索的方法来解决。但是这一题还多了一个记录移动路径的要求。

于是构建结构体,代表每一个位置,结构体中包含dir数组则是为了记录每一步的方向。构造BFS函数,返回的是最后一个位置的结构体,通过这个结构体中的dir数组,配合上初始位置的(0,0)坐标

就可以求出每一次移动的坐标,然后输出。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 using namespace std;
 6 int maze[5][5];
 7 bool visit[5][5];
 8 int dx[4]={1,-1,0,0};//两个数组用于表示移动方向 
 9 int dy[4]={0,0,1,-1};
10 struct Node{
11     int x,y;//表示当前位置的x,y坐标
12     int length;//表示行驶距离
13     int dir[30];//用于记录前面结点移动的方向 
14 };
15 Node &BFS(){
16     queue<Node> que;
17     Node rec,next;
18     rec.x=0;//初始化起点位置的数据 
19     rec.y=0;
20     rec.length=0;
21     que.push(rec);
22     while(que.size()){
23         rec=que.front();
24         que.pop();
25         if(rec.x==4&&rec.y==4) return rec;//到达终点就退出循环
26         for(int i=0;i<4;i++)
27         {
28             int nx=rec.x+dx[i];//表示移动之后的位置 
29             int ny=rec.y+dy[i];
30             if(maze[nx][ny]==0&&nx>=0&&nx<5&&ny>=0&&ny<5&&!visit[nx][ny])//判断当前位置是否满足条件 
31             {    visit[nx][ny]=true;
32                 next=rec;//注意此处next与rec的衔接,这一步是为了记录先前的方向和长度 
33                 next.x=nx;
34                 next.y=ny;
35                 next.length=rec.length+1;
36                 next.dir[rec.length]=i;
37                 que.push(next);
38             } 
39         }
40     }
41 } 
42 int main(){
43     for(int i=0;i<5;i++)
44         for(int j=0;j<5;j++)
45             cin>>maze[i][j];
46     memset(visit,false,sizeof(visit));
47     Node last=BFS();
48     printf("(0, 0)\n");
49     int x=0,y=0;
50     for(int i=0;i<last.length;i++)
51     {
52         
53         x+=dx[last.dir[i]];
54         y+=dy[last.dir[i]];
55         printf("(%d, %d)\n",x,y);
56     }
57     return 0;
58 }

 

T3 POJ-2251 

问题分析:这是一个迷宫最短路径问题,只不过把以前二维的迷宫变成了三维的迷宫。只要把以前二维的bfs算法延伸到三维即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 using namespace std;
 6 struct Node{
 7     int x,y,z;
 8 };
 9 char space[35][35][35];
10 int dis[35][35][35];
11 int L,R,C;
12 int sx,sy,sz;
13 int ex,ey,ez;
14 int dx[]={1,-1,0,0,0,0};
15 int dy[]={0,0,1,-1,0,0};
16 int dz[]={0,0,0,0,1,-1};
17 int bfs(){
18     queue<Node> que;
19     Node t;
20     t.x=sx;
21     t.y=sy;
22     t.z=sz;
23     que.push(t);
24     while(que.size()){
25         Node p=que.front();
26         que.pop();
27         if(p.x==ex&&p.y==ey&&p.z==ez) return dis[ex][ey][ez];
28         for(int i=0;i<6;i++){
29             int nx,ny,nz;
30             nx=p.x+dx[i];
31             ny=p.y+dy[i];
32             nz=p.z+dz[i];
33             if(nx>=0&&nx<L&&ny>=0&&ny<R&&nz>=0&&nz<C&&dis[nx][ny][nz]==0&&space[nx][ny][nz]!='#'){
34                 dis[nx][ny][nz]=dis[p.x][p.y][p.z]+1;
35                 t.x=nx;t.y=ny;t.z=nz;
36                 que.push(t);
37             }
38         }
39     }
40     return dis[ex][ey][ez];
41 }
42 
43 
44 int main(){
45     while(cin>>L>>R>>C){
46         memset(dis,0,sizeof(dis));
47         memset(space,0,sizeof(space));
48         if(L==0&&R==0&&C==0) break;
49         for(int i=0;i<L;i++)
50             for(int j=0;j<R;j++)
51                 for(int k=0;k<C;k++)
52                 {
53                     cin>>space[i][j][k];
54                 }
55     
56     for(int i=0;i<L;i++)
57             for(int j=0;j<R;j++)
58                 for(int k=0;k<C;k++)
59                 {
60                     if(space[i][j][k]=='S') {
61                         sx=i;
62                         sy=j;
63                         sz=k;
64                     }
65                     if(space[i][j][k]=='E') {
66                         ex=i;
67                         ey=j;
68                         ez=k;
69                     }
70                 }
71          int ans= bfs();
72         if(ans==0)  printf("Trapped!\n");
73         else printf("Escaped in %d minute(s).\n",ans);
74     }
75     return 0;
76 }

 

 T4POJ-3278

问题分析:这是一个一维的寻找最短路径的问题,不过起点坐标的变换有向左一步,向右一步,坐标*2三种方式。于是利用三个if语句,进行bfs即可。全局数组初始值为0,所以不用memset();

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 const int maxn=100005;
 6 int N,K;
 7 int visit[maxn];
 8 int step[maxn];
 9 bool let(int u)  
10 {  
11     if(u<0||u>100000||visit[u])  
12         return 0;  
13     return 1;  
14 }  
15 queue<int> que;
16 int bfs(){
17     que.push(N);
18     while(que.size()){
19         int u;
20         u=que.front();
21         que.pop();
22         if(u==K)  {
23             cout<<visit[u];
24             return 0;
25         }
26         if(let(u+1)) {
27             visit[u+1]=visit[u]+1;
28             que.push(u+1);
29         }
30         if(let(u-1)) {
31             visit[u-1]=visit[u]+1;
32             que.push(u-1);
33         }
34         if(let(2*u)) {
35             visit[2*u]=visit[u]+1;
36             que.push(2*u);
37         }
38     }
39 }
40 int main(){
41     cin>>N>>K;
42     bfs();
43     return 0;
44 } 

 

T5   HDU-1312

问题分析:一道简单的DFS搜索题目,因为有多组输入,记得在每次输入之后把标记数组visit清空。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxw=25;
 5 const int maxh=25;
 6 int dx[4]={1,-1,0,0};
 7 int dy[4]={0,0,1,-1}; 
 8 char map[maxw][maxh];
 9 int visit[maxw][maxh];
10 int W,H,ans;
11 void dfs(int x,int y){
12     for(int i=0;i<4;i++){
13         int nx=x+dx[i];
14         int ny=y+dy[i];
15         if(nx>=0&&nx<W&&ny>=0&&ny<H&&map[nx][ny]=='.'&&!visit[nx][ny])
16             {
17                 ans++;
18                 visit[nx][ny]=1;
19                 dfs(nx,ny);
20             }
21     }
22         
23 }
24 int main(){
25     while(cin>>H>>W){
26         memset(visit,0,sizeof(visit));
27         int sx,sy;
28         ans=1;
29         if(W==0&&H==0) break;
30         for(int i=0;i<W;i++)
31             for(int j=0;j<H;j++)
32                 cin>>map[i][j];
33         for(int i=0;i<W;i++)
34             for(int j=0;j<H;j++)
35                 if(map[i][j]=='@'){
36                     sx=i;
37                     sy=j;
38                     break;
39                 }
40         dfs(sx,sy);
41         cout<<ans<<endl;
42     }
43     return 0;
44 }