MCS 搜索 入门DFS 2015-07-26

来源:互联网 发布:淘宝消费人群年龄分布 编辑:程序博客网 时间:2024/05/21 10:14

专题链接:MCS 搜索 入门DFS acmaker

Problem A HDU1243

题意:在一个N*M的图中寻找‘@’的连同块个数

思路:搞了一周搜索后现在重新看起来很简单,当初做的半死

代码如下:

#include<stdio.h>#include<string>int i,j,flag[110][110],m,n,sum;char map[110][110];void DFS(int x,int y) //DFS寻找周围八个点是否也含有@且未访问过,若含有@切未访问过则标记 ,继续下一层搜索 {if(map[x-1][y-1]=='@'&&flag[x-1][y-1]==0){flag[x-1][y-1]=1;DFS(x-1,y-1);}if(map[x-1][y]=='@'&&flag[x-1][y]==0){flag[x-1][y]=1;DFS(x-1,y);}if(map[x-1][y+1]=='@'&&flag[x-1][y+1]==0){flag[x-1][y+1]=1;DFS(x-1,y+1);}if(map[x][y+1]=='@'&&flag[x][y+1]==0){flag[x][y+1]=1;DFS(x,y+1);}if(map[x+1][y+1]=='@'&&flag[x+1][y+1]==0){flag[x+1][y+1]=1;DFS(x+1,y+1);}if(map[x+1][y]=='@'&&flag[x+1][y]==0){flag[x+1][y]=1;DFS(x+1,y);}if(map[x+1][y-1]=='@'&&flag[x+1][y-1]==0){flag[x+1][y-1]=1;DFS(x+1,y-1);}if(map[x][y-1]=='@'&&flag[x][y-1]==0){flag[x][y-1]=1;DFS(x,y-1);}} int main(){while(scanf("%d%d",&m,&n),m){getchar();sum=0;    memset(flag,0,sizeof(flag));     memset(map,'*',sizeof(map));for(i=1;i<=m;i++){scanf("%s",map[i]+1);}for(i=1;i<=m;i++){for(j=1;j<=n;j++)  if(map[i][j]=='@'&&flag[i][j]==0)//每次读到@切未访问过时,联通块个数加1   {  flag[i][j]==1;  DFS(i,j);  sum++;  }}printf("%d\n",sum);}return 0;} 

查找八个点时可以用一个for循环,当初傻傻没想到重复写了八个if判断,若干次以后,由二狗提点才醒悟。


Problem B HDU1312

题意:在一个W行H列的含有’.'   '#'  '@'  的图中,由@为起点,’#‘为墙,不可通过,查找’.‘的个数 

思路:明显的dfs过。

代码:

#include<stdio.h>#include<string>char p[22][22];int flag[22][22],h,w,sum,a=0;void DFS(int x,int y)                          //DFS查找周围的点是否为'.',并标记{if(p[x-1][y]=='.'&&flag[x-1][y]==0){sum++;flag[x-1][y]=1;DFS(x-1,y);}if(p[x+1][y]=='.'&&flag[x+1][y]==0){sum++;flag[x+1][y]=1;DFS(x+1,y);}if(p[x][y-1]=='.'&&flag[x][y-1]==0){sum++;flag[x][y-1]=1;DFS(x,y-1);}if(p[x][y+1]=='.'&&flag[x][y+1]==0){sum++;flag[x][y+1]=1;DFS(x,y+1);}}int main(){int m,n;while(scanf("%d%d",&w,&h),w+h){getchar();memset(p,'#',sizeof(p) );memset(flag,0,sizeof(flag));sum=0;for(int i=1;i<=h;i++)  {  for(int j=1;j<=w;j++)    {        scanf("%c",&p[i][j]);    if(p[i][j]=='@')                       //记录起点坐标    {    flag[i][j]=1;    m=i;n=j;    sum++;    }        }    getchar();  }        DFS(m,n);printf("%d\n",sum,a);}return 0;} 

代码总是写的很丑,经常自己都看不懂。。



Problem C HDU1010

题意:给一个N*M的图,以及时间T,图中含有’X' 'S' 'D' '.'等符号。'X'为墙,S为起点,D为终点, ‘  . '为路,且走过的路不能再走,求在T时间时能否刚好到达D。

思路:dfs搜索所有路,将走过的路标记,在到达终点时,若时间为T,则返回。

代码:

#include<stdio.h>#include<string>char map[10][10];int flag[10][10],i,j,m,n,t,sum,sx,sy,ex,ey,l,ok;void DFS(int x,int y,int l){if(l==t){if(map[x][y]=='D'){ok=1;return;}}else if(map[x][y]=='D')return;flag[x][y]=1;                                //将x,y点标记为走过 if((map[x-1][y]=='.'||map[x-1][y]=='D')&&flag[x-1][y]==0){DFS(x-1,y,l+1);if(ok)return ;}if((map[x+1][y]=='.'||map[x+1][y]=='D')&&flag[x+1][y]==0){DFS(x+1,y,l+1);if(ok)return ;}if((map[x][y-1]=='.'||map[x][y-1]=='D')&&flag[x][y-1]==0){DFS(x,y-1,l+1);if(ok)return ;}if((map[x][y+1]=='.'||map[x][y+1]=='D')&&flag[x][y+1]==0){DFS(x,y+1,l+1);if(ok)return ;}flag[x][y]=0;                        //当一层调用结束,返回上一层时将标记还原 为未走过 }int main(){while(scanf("%d%d%d",&m,&n,&t),m+n+t){getchar();ok=0;sum=0;l=0;memset(map,'X',sizeof(map));    memset(flag,0,sizeof(flag));for(i=1;i<=m;i++)  {  for(j=1;j<=n;j++)  {  scanf("%c",&map[i][j]);  if(map[i][j]=='S')//起点   {  sx=i;sy=j;  }  if(map[i][j]=='D')//终点   {  ex=i;ey=j;  }  if(map[i][j]=='.')  {  sum++;  flag[i][j]=0;  }  }   getchar();  }  if((ex+ey-sx-sy-t)%2==0&&t<=sum+1)  DFS(sx,sy,l);  printf(ok?"YES\n":"NO\n") ;    }return 0;} 

第一天做得这三题基本都是上网看了题解后才会写的。






0 0
原创粉丝点击