DFS-hdu-2821-Pusher
题目链接:
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)
Problem Description PusherBoy is an online game http://www.hacker.org/push . There is an R * C grid, ...
- hdu 2821 Pusher (dfs)
Pusher Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others)Total Subm ...
- hdu 2821 Pusher (dfs)
把这个写出来是不是就意味着把 http://www.hacker.org/push 这个游戏打爆了? ~啊哈哈哈 其实只要找到一个就可以退出了 所以效率也不算很低的 可以直接DFS呀呀呀呀 ...
- HDU 2821 Pusher
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2821 首先,题目描述给的链接游戏很好玩,建议先玩几关,后面越玩越难,我索性把这道题A了,也就相当于通关 ...
- hdu 2821(dfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2821 思路:一开始的时候没注意到,必须从map[i][j]==0的位置开始,然后就是dfs了,回溯的时 ...
- hdu 2821 学习一点dfs的小技巧吧。。 还是自己太弱了
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c ...
- DFS hdu 1016
http://acm.hdu.edu.cn/showproblem.php?pid=1016 #include <iostream> using namespace std; int a[ ...
- 变形课(DFS hdu 1181)
变形课 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submis ...
- Tree and Permutation dfs hdu 6446
Problem Description There are N vertices connected by N−1 edges, each edge has its own length.The se ...
- DFS || HDU 2181
题意:一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市. 前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每 ...
随机推荐
- Spring Assert主张 (参议院检测工具的方法-主张)
Web 收到申请表格提交的数据后都需要对其进行合法性检查,假设表单数据是不合法的,该请求将被拒绝.分类似的,当我们写的类方法,该方法还经常需要组合成参 法国检查.假设参议院不符合要求,方法通过抛出异常 ...
- WEB 3D SVG CAD 向量 几个实施
一.他们所有的发展.从地上爬起来 VML+SVG发展矢量地图.你并不需要导入第三方的图片作为背景,直接在地图编辑器可以在底图内容编辑,由于岩石.巷道.煤层.画水.础地图样子再在其上面画出智慧线等设备, ...
- UVA - 12338 Anti-Rhyme Pairs (哈希)
Description D Anti-Rhyme Pairs Input: Standard Input Output: Standard Output Often two words that rh ...
- hdu 4864 Task (馋)
# include <stdio.h> # include <algorithm> # include <string.h> using namespace std ...
- OOP思想
OOP思想 读者朋友们大家好,我们今天这一讲就接着前面的封装继续讲解,今天就是在前面内容上面的升级,OOP思想中的继承,我们就先来解释一下继承到底是什么意思,我们在什么地方会用到继续. 继承就是,后代 ...
- fiddler打开后 浏览器就上不了网的解决方法
fiddler设置一下即可 Tools fiddler options connections 不要选中 Act as system proxy on startup
- Java程序猿从底层到CTO的技术路线图
首先.附一张图片展示所在各个阶段的工作职能: 其次.文字型描写叙述所在各个阶段的工作职能: Java程序猿 高级特性 反射.泛型.凝视符.自己主动装箱和拆箱.枚举类.可变參数.可变返回类型.增强循环. ...
- STL源代码剖析(一) - 内存分配
Allocaor allocator 指的是空间配置器,用于分配内存.STL中默认使用SGI STL alloc作为STL的内存分配器,尽管未能符合标准规格,但效率上更好.SGI STL也定义有一个符 ...
- MySQL存储过程:用户授权量
写这些脚本需求放缓的调查记录到数据库,方便观看. 1. 因为默认mysql.slow_log表使用csv数据引擎,该数据不支持指数,因此,有必要改变MyISAM发动机.和query_time字段索引, ...
- 动态生成Zip
动态生成Zip文档 通过前面一篇烂文的介绍,大伙儿知道,ZipArchive类表示一个zip文档实例,除了用上一篇文章中所列的方法来读写zip文件外,还可以直接通过ZipArchive类,动态生成 ...