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行以后每 ...
随机推荐
- 3g自己主动更新网卡驱动web完架构文档
几年前写. 看它是否是用得上 1 简单介绍 本文档具体描写叙述了基于ASP.NET平台和IIS服务的T-Mobile自己主动更新系统的实现框架. 本文档主要从技术架构和业务架构两个方面来着手来描写叙 ...
- LCA 学习算法 (最近的共同祖先)poj 1330
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20983 Accept ...
- javascript有用小技巧—实现分栏显示
记得给师哥师姐測试考试系统的时候,看到他们的考试页面能够实现隐藏左边的考生信息部分,当时认为好高大上.好人性化. 如今学了javascript,我也能实现这个功能了,以下来显摆一下. 1.页面设计: ...
- A左右ndroid正在使用Uri监视数据库中的更改
在监控数据库在线原创文章是非常小的变化,基本上没有找到一个实际的问题.所以,如果你看到一个有点蓝牙源代码,写一个Demo.在这里,供大家参考,查看源代码: src有三个文件MyDataProvider ...
- EJB学习笔记
1 J2ee概述 J2ee是企业级的计算平台,它为分布式和基于组件的软件开发提供了一个“操作系统” Ant是什么工具?? EJB: 什么是EJB? 是一种server端组件结构,简化了开发分布式企 ...
- Hibernate 学习教程
第1课 课程内容. 6 第2课Hibernate UML图. 6 第3课 风格. 7 第4课 资源. 7 第5课 环境准备. 7 第6课 第一个演示样例HibernateHelloWorld 7 第7 ...
- c++输入密码以星号代替
#include <iostream> #include <string>//注意这里的头文件! #include<conio.h> using namespace ...
- 给Activity设置Dialog属性,点击区域外消失;
1.在AndroidManifest.xml中给Activity设置样式: <activity android:name=".MyActivity" ...
- TextView于getCompoundDrawables()使用演示样本的方法
MainActivity例如下列: package cc.testcompounddrawables; import android.app.Activity; import android.grap ...
- android 反编译,反,注射LOG
反编译smali注射显示LOG该代码.以后使用: .class public Lnet/iaround/connector/DebugClass; .super Ljava/lang/Object; ...