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行以后每 ...
随机推荐
- uva live 6190 Beautiful Spacing (二分法+dp试 基于优化的独特性质)
I - Beautiful Spacing Time Limit:8000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu ...
- Nginx各版本的区别
Nginx官网提供了三个类型的版本Mainline version:Mainline 是 Nginx 目前主力在做的版本,可以说是开发版Stable version:最新稳定版,生产环境上建议使用的版 ...
- ASP.NET5
ASP.NET5 2015年11月30日, ASP.NET 5 RC1 已经发布,本文尝试了一下ASP.NET5项目的创见一发布到IIS.开发环境,win10 64位,visual studio201 ...
- 关于csrss.exe和winlogon.exe进程多、占用CPU高的解决办法
原地址 http://blog.sina.com.cn/s/blog_912e77480101nuif.html 最近VPS的CPU一直处在100%左右,后台管理上去经常打不开,后来发现上远程都要 ...
- telnet发电子邮件
无聊今天的工作,想想一个学生被提到最后一次telnet发电子邮件,所以我想试试.最后,成功的实践,这里做个总结. 首先,cmd进telnet打开回话: 下面红色字体为命令. 1.open smtp.1 ...
- 【Android基础】Activity之间进行参数传递的三种方式
1.使用Intent进行传输 //发送数据的Activity class button implements OnClickListener{ @Override public void onClic ...
- 最小二乘法 (转)good
最小二乘法也称为最小平方法,是一种数据优化技术,它通过最小化误差的平方和寻找数据的最佳函数匹配. 最小二乘法最初由高尔顿在创立回归分析的时候提出,现在已经成为探索变量间关系最重要的方法,最小二乘法根据 ...
- scrot-0.8
相关库下载地址: www.sunfreeware.com/programlistsparc10.html tar -zxvf scrot-0.8.tar.gzcd scrot-0.8. ...
- MonkeyRunner源代码分析Android通信设备
正如前面<谁动了我的截图?--Monkeyrunner takeSnapshot方法源代码跟踪分析>所述,本文主要会尝试描写叙述android的自己主动化測试框架MonkeyRunner到 ...
- 每天进步一点点-->函数fseek() 使用方法
在阅读代码时,遇到了非常早之前用过的fseek(),非常久没实用了,有点陌生,写出来以便下次查阅. 函数功能是把文件指针指向文件的开头,须要包括头文件stdio.h fseek 函数名: fsee ...