从零单排4

来源:互联网 发布:淘宝订单险有用吗 编辑:程序博客网 时间:2024/04/29 21:50

2. 学会BFS与DFS

今天上午练习了一些简单的bfs和dfs,收获挺多的,越写越像模版题了~~

下午这个教室好像要用作考场擦擦擦

下午继续做bfs和dfs~

以下是题解:


hdu 1241:http://acm.hdu.edu.cn/showproblem.php?pid=1241

/*dfs从每一个@出发,count+1,dfs其八个方向,遇到@即将它置为**/#include<iostream>#define N 105using namespace std;int m,n;char map[N][N];int dx[8]={1,1,0,-1,-1,-1,0,1};int dy[8]={0,1,1,1,0,-1,-1,-1};bool check(int x,int y){if(x>=0&&x<m&&y>=0&&y<n){return true;}else {return false;}}void dfs(int sx,int sy){map[sx][sy]='*';int x,y;for(int i=0;i<8;i++){x=sx+dx[i];y=sy+dy[i];if(check(x,y)&&map[x][y]=='@'){dfs(x,y);}}}int main(){while(cin>>m>>n,m!=0&&n!=0){int count=0;for(int i=0;i<m;i++){cin>>map[i];}for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(map[i][j]=='@'){count++;dfs(i,j);}}}cout<<count<<endl;}system("pause");return 0;}

hdu 1242:http://acm.hdu.edu.cn/showproblem.php?pid=1242

/*bfs模版题先不继续做了听会儿组合数学课!*/#include<iostream>#include<queue>using namespace std;int n,m;int i,j;char map[205][205];int visit[205][205];int dx[4]={0,1,0,-1};int dy[4]={1,0,-1,0};struct node{int x;int y;int step;};queue<node>q;node s;node next;int check(int x, int y) {if(x < 0 || x > n || y < 0 || y > n||map[next.x][next.y]=='#')  return 0; else  return 1;}void bfs(){int i; while(!q.empty())   q.pop(); memset(visit, 0, sizeof(visit));  q.push(s);  visit[s.x][s.y] = 1;  while(!q.empty()) {  s = q.front();  q.pop();       if(map[s.x][s.y]=='r')   {cout<<s.step<<endl;return ;}if(map[s.x][s.y]=='x'){map[s.x][s.y]='.';s.step++;q.push(s);}else{for(i=0;i<4;i++){   next.x = dx[i] + s.x;     next.y = dy[i] + s.y;     next.step = s.step + 1;             if(!check(next.x, next.y))    continue;     if(!visit[next.x][next.y])   {    q.push(next);    visit[next.x][next.y] = 1;          }}  } } cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;}//end of BFS()int main(){while(cin>>n>>m){memset(visit,0,sizeof(visit));for(int i=0;i<n;i++){getchar();for(int j=0;j<m;j++){cin>>map[i][j];if(map[i][j]=='a'){s.x=i;s.y=j;s.step=0;}}}bfs();}system("pause");return 0;}

hdu 1312:http://acm.hdu.edu.cn/showproblem.php?pid=1312

/*简单dfs先判再搜 注意将@变为.*/#include<iostream>using namespace std;int dx[4]={1,0,-1,0};int dy[4]={0,1,0,-1};int n,m;int cnt;int sx,sy;char map[25][25];void dfs(int x,int y){if(map[x][y]!='.'||x<0||x>=m||y<0||y>=n){return ;}cnt++;map[x][y]='#';for(int i=0;i<4;i++){int nextx=x+dx[i];int nexty=y+dy[i];dfs(nextx,nexty);}}int main(){while(cin>>n>>m,n!=0&&m!=0){cnt=0;getchar();for(int i=0;i<m;i++){cin>>map[i];//puts(map[i]);}for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(map[i][j]=='@'){sx=i;sy=j;map[i][j]='.';}}}dfs(sx,sy);cout<<cnt<<endl;}system("pause");return 0;}

hdu 1372:http://acm.hdu.edu.cn/showproblem.php?pid=1372

/*简单bfs~竟然得了一个output limit exceeded原来是输入没有判定EOF。。。*/#include<iostream>#include<cstdio>#include<queue>using namespace std;struct node{int x;int y;int step;};node s;node next;queue<node>q;int dx[8]={2,1,-1,-2,-2,-1,1,2};int dy[8]={1,2,2,1,-1,-2,-2,-1};int sx,sy,ex,ey;int visit[9][9];char s1[5],s2[5];int check(int x,int y){if(x>=0&&x<8&&y>=1&&y<=8){return 1;}else{return 0;}}void bfs(){memset(visit,0,sizeof(visit));while(!q.empty()){q.pop();}s.x=sx;s.y=sy;s.step=0;visit[s.x][s.y]=1;q.push(s);while(!q.empty()){s=q.front();q.pop();if(s.x==ex&&s.y==ey){printf("To get from %s to %s takes %d knight moves.\n",s1,s2,s.step);return ;}for(int i=0;i<8;i++){next.x=s.x+dx[i];next.y=s.y+dy[i];next.step=s.step+1;if(!visit[next.x][next.y]&&check(next.x,next.y)){visit[next.x][next.y]=1;q.push(next);}}}}int main(){while(scanf("%s%s",s1,s2)!=EOF){sx=s1[0]-'a';sy=s1[1]-'0';ex=s2[0]-'a';ey=s2[1]-'0';bfs();}system("pause");return 0;}

hdu 1072:http://acm.hdu.edu.cn/showproblem.php?pid=1072

/*很有意义的bfs这题wa了一次因为没有将map[i][j]=4的点在遍历后设为0(不可到达)可以这样想如果这个重置点可以多次进入的话,那么每次时间都会重设为6,然后又从该点进行同样的上下左右方向的遍历,自然就进入死循环了。。。 */#include<iostream>#include<queue>using namespace std;struct node{int x;int y;int step;int time;};node s;node next;queue<node>q;int dx[4]={1,0,-1,0};int dy[4]={0,1,0,-1};int map[9][9];int n,m;int sx,sy,ex,ey;int check(int x,int y){if(x>=0&&x<n&&y>=0&&y<m){return 1;}else{return 0;}}void bfs(){while(!q.empty()){q.pop();}s.x=sx;s.y=sy;s.step=0;s.time=6;q.push(s);while(!q.empty()){s=q.front();q.pop();if(s.x==ex&&s.y==ey&&s.time>0){cout<<s.step<<endl;return ;}for(int i=0;i<4;i++){next.x=s.x+dx[i];next.y=s.y+dy[i];next.step=s.step+1;next.time=s.time-1;if(check(next.x,next.y)&&map[next.x][next.y]!=0&&next.time>0){if(map[next.x][next.y]==4){map[next.x][next.y]=0;next.time=6;}q.push(next);}}}cout<<"-1"<<endl;}int main(){int T;cin>>T;while(T--){cin>>n>>m;for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>map[i][j];if(map[i][j]==2){sx=i;sy=j;}if(map[i][j]==3){ex=i;ey=j;}}}bfs();}system("pause");return 0;}

hdu 1240:http://acm.hdu.edu.cn/showproblem.php?pid=1240

/*三维bfs一开始老是错最后打印起始坐标发现输入不正确三维的时候一定要注意输入的对应关系。。。1A*/#include<iostream>#include<queue>using namespace std;struct node{int x;int y;int z;int step;};node s;node next;queue<node>q;int dx[6]={1,0,-1,0,0,0};int dy[6]={0,1,0,-1,0,0};int dz[6]={0,0,0,0,1,-1};char map[11][11][11];int n;int sx,sy,sz,ex,ey,ez;int visit[11][11][11];int check(int x,int y,int z){if(x>=0&&x<n&&y>=0&&y<n&&z>=0&&z<n){return 1;}else{return 0;}}void bfs(){memset(visit,0,sizeof(visit));while(!q.empty()){q.pop();}s.x=sx;s.y=sy;s.z=sz;s.step=0;visit[s.x][s.y][s.z]=1;q.push(s);while(!q.empty()){s=q.front();q.pop();if(s.x==ex&&s.y==ey&&s.z==ez){printf("%d %d\n",n,s.step);return ;}for(int i=0;i<6;i++){next.x=s.x+dx[i];next.y=s.y+dy[i];next.z=s.z+dz[i];next.step=s.step+1;if(!visit[next.x][next.y][next.z]&&check(next.x,next.y,next.z)&&map[next.x][next.y][next.z]=='O'){visit[next.x][next.y][next.z]=1;q.push(next);}}}printf("NO ROUTE\n");}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);char s1[10],s2[10];char temp[10];while(scanf("%s%s",s1,s2)!=EOF){n=s2[0]-'0';for(int k=0;k<n;k++){for(int i=0;i<n;i++){getchar();for(int j=0;j<n;j++){scanf("%c",&map[i][j][k]);}}}scanf("%d%d%d",&sx,&sy,&sz);//printf("%c\n",map[sx][sy][sz]);scanf("%d%d%d",&ex,&ey,&ez);//printf("%c\n",map[ex][ey][ez]);scanf("%s",temp);bfs();}system("pause");return 0;}

hdu 1548:http://acm.hdu.edu.cn/showproblem.php?pid=1548

/*bfs~这个题又折腾了好久。。。由于将n同时设为全局变量和局部变量导致传到bfs()里的n一直为0。。。。*/#include<iostream>#include<queue>using namespace std;struct node{int x;int step;};node s;node next;queue<node>q;int start,end;int map[205];int visit[205];int n;int dx[2]={1,-1};int check(int x){if(x>=1&&x<=n){//cout<<"hehe"<<endl;return 1;}else{return 0;}}void bfs(){memset(visit,0,sizeof(visit));while(!q.empty()){q.pop();}s.x=start;s.step=0;visit[s.x]=1;q.push(s);while(!q.empty()){s=q.front();q.pop();if(s.x==end){cout<<s.step<<endl;return ;}for(int i=0;i<2;i++){next.x=s.x+dx[i]*map[s.x];;next.step=s.step+1;//cout<<next.x<<endl;//cout<<n<<endl;//cout<<check(next.x)<<endl;//cout<<visit[next.x]<<endl;if(check(next.x)&&!visit[next.x]){q.push(next);visit[next.x]=1;}}}cout<<"-1"<<endl;}int main(){while(cin>>n&&n!=0){//cout<<n<<endl;cin>>start>>end;for(int i=1;i<=n;i++){cin>>map[i];}bfs();}system("pasue");return 0;}

hdu 2181:http://acm.hdu.edu.cn/showproblem.php?pid=2181

/*dfs模版题好好体会一下。。。*/#include<iostream>using namespace std;int map[25][3];int visit[25];int result[25];int num=1;int end;void dfs(int m,int len)//从m出发的长度为len的序列 {result[len]=m;visit[m]=1;for(int i=0;i<3;i++){int temp=map[m][i];if(temp==end&&len==19){cout<<num++<<":"<<"  ";for(int j=0;j<20;j++){cout<<result[j]<<" ";}cout<<end<<endl;}if(!visit[temp]){dfs(temp,len+1);}}visit[m]=0;}int main(){for(int i=1;i<=20;i++){cin>>map[i][0]>>map[i][1]>>map[i][2];}int m;while(cin>>m&&m!=0){end=m;memset(visit,0,sizeof(visit));dfs(m,0);}system("pause");return 0;}

hdu 2553:http://acm.hdu.edu.cn/showproblem.php?pid=2553

/*dfs N皇后问题 感觉对dfs没有完全掌握。。。自己写的时候总是弄不明白本质。。*/#include<iostream>#include<cstdio>#include<cmath>#include<cstring>using namespace std;struct point{    int x,y;}a[11];int num,cnt;int judge(int n,int x,int y){    int i;    for(i=0;i<n;i++){        if(a[i].y==y||abs(a[i].x-x)==abs(a[i].y-y))            return 0;    }    return 1;}void dfs(int n,int r)//按行dfs {    int i;    if(n==num){        cnt++;        return;    }    for(i=1;i<=num;i++)    {if(judge(n,r,i)){            a[n].x=r;            a[n].y=i;            dfs(n+1,r+1);        }}    return;}int main(){    int ans[11];    for(num=1;num<11;num++){        cnt=0;        dfs(0,1);        ans[num]=cnt;    }    while(scanf("%d",&num),num)        printf("%d\n",ans[num]);    return 0;}
dfs没有完全弄懂。。。

不过大体流程应该是:

判定是否到达目标条件->继续遍历其他结点

在以后遇到综合问题的时候再去深入学习吧~


原创粉丝点击