DFS-hdu-2821-Pusher
来源:互联网 发布:蓝桥杯单片机 编辑:程序博客网 时间:2024/06/07 00:18
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2821
题目意思:
给一个n*n的矩阵,里面有些位置是空的,有些位置有箱子(a代表一个箱子,b代表两个,依此类推)。让你选择一个空位置作为起点,然后每步选择一个方向(上,下,左,右)走,直到碰到箱子为止,然后将此位置的箱子移走一个,剩下的箱子全部合并到下一位置。要求:必须与箱子隔超过1个位置的时候才能移。
求一个开始位置使得能够移除所有的箱子,并输出行走路线。
经数据检测两点注意:1、不含边缘位置超过一个箱子的情况,2、保证有解。
解题思路:
枚举开始位置,DFS深搜,有一条路径能全部移走箱子,则输出。
注意保存回溯现场(不要用全局变量来保存现场,因为在递归调用的时候会覆盖原来保存的现场,wa了好几次)。
代码:
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#define eps 1e-6#define INF 0x1f1f1f1f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;/*freopen("data.in","r",stdin);freopen("data.out","w",stdout);*/char save[30][30],save1[30][30];int c,r,dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};int lim,cnt;char di[4]={'U','R','D','L'};struct Inf{ int x,y;}s;bool iscan(Inf & tt,int dd){ int xx=tt.x+dir[dd][0],yy=tt.y+dir[dd][1]; if(xx<0||xx>=r||yy<0||yy>=c) //下一步出界了,不行 return false; if(save1[xx][yy]!='.') //下一步就是箱子不行 return false; while(save1[xx][yy]=='.') //在该方向走,直到靠近箱子为止 { xx=xx+dir[dd][0],yy=yy+dir[dd][1]; if(xx<0||xx>=r||yy<0||yy>=c)//走出去了,不行 return false; } if(save1[xx][yy]=='a')//该位置只有一个箱子 { cnt++; save1[xx][yy]='.'; tt.x=xx,tt.y=yy; return true; } else //该位置有多个箱子 { int x=xx+dir[dd][0],y=yy+dir[dd][1]; if(x<0||x>=r||y<0||y>=c) //边缘有多个箱子的情况 { //cnt++; //tt.x=xx,tt.y=yy; //save1[xx][yy]=save1[xx][yy]-1; //return true; //两种写法都可以,其他写法也行,因为测试数据中不存在这种情况 return false; } cnt++; tt.x=xx,tt.y=yy; if(save1[x][y]!='.') //下一位置如果不是.的话,直接合并 save1[x][y]=save1[x][y]+save1[xx][yy]-'a';//注意-'a' else //下一位置是.的话,直接拿过来 save1[x][y]=save1[xx][yy]-1; save1[xx][yy]='.'; return true; }}bool flag;string an;void dfs(Inf cur,string ans){ if(flag) //已找到一条路径 return ; char tt[30][30];//注意保存现场时要用局部变量 for(int i=0;i<4;i++) //沿四个方向走 { memcpy(tt,save1,sizeof(save1)); Inf tmp=cur; int temp=cnt; //便于回溯的时候,其他没有改变 /*if(test) { for(int j=0;j<r;j++) printf("%d %s\n",j,save1[j]); }*/ if(!iscan(tmp,i)) continue; /* if(test) { printf("%d %d->%d %d cnt:%d\n",cur.x,cur.y,tmp.x,tmp.y,cnt); putchar('\n'); for(int j=0;j<r;j++) printf("%d %s\n",j,save1[j]); }*/ string tm=ans; tm+=di[i]; if(cnt==lim) //找到了一条路径能全部移完 { an=tm; flag=true; return ; } dfs(tmp,tm); cnt=temp; //回溯 memcpy(save1,tt,sizeof(tt)); }}int main(){ while(~scanf("%d%d",&c,&r)) { lim=0; for(int i=0;i<r;i++) { scanf("%s",save[i]); for(int j=0;j<c;j++) if(save[i][j]!='.') lim+=(save[i][j]-'a'+1); //统计箱子个数 } //putchar('\n'); flag=false; for(int i=0;i<r&!flag;i++) for(int j=0;j<c&&!flag;j++) { if(save[i][j]!='.') //枚举开始位置,注意开始位置不为 continue; s.x=i,s.y=j; cnt=0; memcpy(save1,save,sizeof(save)); dfs(s,""); if(flag) { printf("%d\n%d\n",i,j); cout<<an<<endl; } } } return 0;}
- DFS-hdu-2821-Pusher
- HDU-2821-Pusher(DFS)
- hdu 2821 Pusher DFS
- hdu 2821 Pusher (dfs)
- hdu 2821 Pusher(dfs)
- hdu 2821 Pusher (水dfs)
- 【搜索】 HDU 2821 Pusher DFS
- HDU 2821Pusher(DFS )
- HDU 2821 Pusher
- HDU 2821 Pusher
- HDU 2821 Pusher
- HDU 2821 Pusher
- HDU 2821--Pusher
- HDU 2821 Pusher
- hdu 2821 pusher 4.3.7
- hdu 2821 Pusher 附几组数据
- (HDU 2821)Pusher DFS + 在一个方向上可以移动多位
- HDU2821 Pusher(DFS)
- Hibernate一对多(单向)
- ids for thisclass must be manually assigned before callingsave()
- spring - context:component-scan
- Struts2输入校验总结
- [自学问题总结]const 和 static readonly 区别
- DFS-hdu-2821-Pusher
- 商业智能给数据获取带来的局部效益案例
- Android编程习惯
- Java IO学习笔记:概念与原理
- java.io.IOException: Attempted read from closed stream.
- IWorkspaceFactory Create Example创建个人mdb、file_mdb、sde
- js-知识2
- my first Grails application
- 需要检查