http://acm.hdu.edu.cn/showproblem.php?pid=2216
zjt和sara在同一个地图里,zjt要去寻找sara,zjt每移动一步sara就要往相反方向移动,如果他们相邻或者在同一个格子里就算相遇。
输出最少步数。注意zjt每次必须要有能移动的点才移动,否则不能移动,但是sara没有能移动的点的话可以呆着不动。
用结构体保存两个点和相应的步数作为一个状态,然后用哈希函数映射出每一个状态的的哈希值,放入set中,判重。
注意哈希函数的选取要确保不能重复。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set> using namespace std; struct PT
{
int x1,y1,x2,y2;
int step;
}; const int dir_x[]={,,,-};
const int dir_y[]={,-,,};
char mp[][];
int n,m; int ha(int a,int b,int c,int d)
{
int ret=a;
ret=ret*+b;
ret=ret*+c;
ret=ret*+d;
return ret;
} int main()
{
//freopen("a.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
int a=,b=,c=,d=;
for(int i=;i<n;i++) scanf("%s",mp[i]);
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
if(mp[i][j]=='Z')
{
a=i;b=j;
}
else if(mp[i][j]=='S')
{
c=i;d=j;
}
}
}
//printf("%d %d %d %d\n",a,b,c,d);
PT ac=(PT){a,b,c,d,}; queue<PT> q;
q.push(ac);
set<int> st;
st.insert(ha(a,b,c,d));
bool flag=false;
while(!q.empty())
{
PT u=q.front(),v; q.pop();
int x=abs(u.x1-u.x2)+abs(u.y1-u.y2);
if(x==||x==) //相邻或者相遇
{
printf("%d\n",u.step);
flag=true;
break;
}
for(int i=;i<;i++)
{
int X1=u.x1+dir_x[i],X2=u.x2-dir_x[i];
int Y1=u.y1+dir_y[i],Y2=u.y2-dir_y[i];
if(X1<||X1>=n||Y1<||Y1>=m||mp[X1][Y1]=='X')
{
continue;
}
if(X2<||X2>=n||Y2<||Y2>=m||mp[X2][Y2]=='X')
{
X2=X2+dir_x[i];Y2=Y2+dir_y[i];
}
// printf("%d %d %d %d\n",X1,Y1,X2,Y2);
int xx=u.step+;
int h=ha(X1,Y1,X2,Y2);
if(!st.count(h))
{
st.insert(h);
v=(PT){X1,Y1,X2,Y2,xx};
q.push(v);
}
}
}
if(!flag) cout<<"Bad Luck!\n";
}
return ;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set> using namespace std; struct point
{
int x1,y1,x2,y2;
int step;
}; const int dx[]={,,,-};
const int dy[]={,-,,};
char mp[][];
int n,m;
int used[][][][];
bool flag; void bfs(point s)
{
memset(used,,sizeof(used));
queue<point>que;
que.push(s);
used[s.x1][s.y1][s.x2][s.y2]=;
while(!que.empty())
{
point e=que.front(); que.pop();
int x=abs(e.x1-e.x2)+abs(e.y1-e.y2);
// printf("%d %d %d %d\n",e.x1,e.y1,e.x2,e.y2);
if(x==||x==)
{
flag=;
printf("%d\n",e.step);
return;
}
for(int i=;i<;i++)
{
s=e;
s.x1=e.x1+dx[i];s.y1=e.y1+dy[i];
if(s.x1<||s.x1>=n||s.y1<||s.y1>=m||mp[s.x1][s.y1]=='X') continue;
s.x2=e.x2-dx[i];s.y2=e.y2-dy[i];
if(s.x2<||s.x2>=n||s.y2<||s.y2>=m||mp[s.x2][s.y2]=='X')
{
s.x2+=dx[i];s.y2+=dy[i];
}
if(!used[s.x1][s.y1][s.x2][s.y2])
{
used[s.x1][s.y1][s.x2][s.y2]=;
s.step+=;
que.push(s);
}
}
}
}
int main()
{
//freopen("a.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
point s;
for(int i=;i<n;i++) scanf("%s",mp[i]);
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
if(mp[i][j]=='Z')
{
s.x1=i;s.y1=j;
}
else if(mp[i][j]=='S')
{
s.x2=i;s.y2=j;
}
}
}
s.step=;
flag=;
bfs(s);
if(!flag) printf("Bad Luck!\n");
}
return ;
}
http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1187
这道题以前看到没有思路去做,今天终于ac了。
跟上面一道题不同的是这里两个点是按照相同的指令移动,并且如果发出指令之后移动到了不合法的位置那么就忽略这条指令那么点应该返回到原来的位置,但是在还是需要记录这条指令 还有一个坑点是输出尽可能短的指令,如果长度相同输出字典序最小的指令,所以遍历四个方向是有先后顺序的,昨晚debug了一个小时才发现这个。
思路跟上面一样。
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <iostream>
using namespace std; struct point
{
int x1,y1,x2,y2;
string str;
}; char maze[][];
int n,m;
bool flag;
string go;
int dx[]={,,,-};
int dy[]={,-,,};
char dir[]={'D','L','R','U'}; //注意 顺序必须是这样 跟上面对应
int hash1(point s)
{
int cnt=s.x1;
cnt=cnt*+s.y1;
cnt=cnt*+s.x2;
cnt=cnt*+s.y2;
return cnt;
} void bfs(point s)
{
queue<point>que;
set<int>st;
que.push(s);
st.insert(hash1(s));
while(!que.empty())
{
point e=que.front(); que.pop();
//printf("%d %d %d %d\n",e.x1,e.y1,e.x2,e.y2);
if(flag&&e.str.size()>go.size()) break;
if(e.x1==e.x2&&e.y1==e.y2)
{
// cout<<e.str<<endl;
if(go.size()==)
{
go=e.str;
}
else if(go>e.str) go=e.str;
flag=true;
}
for(int i=;i<;++i)
{
s.x1=e.x1+dx[i],s.x2=e.x2+dx[i];
s.y1=e.y1+dy[i],s.y2=e.y2+dy[i];
// printf("%d %d %d %d \n",s.x1,s.y1,s.x2,s.y2);
if(s.x1<||s.x1>=n||s.y1<||s.y1>=m||maze[s.x1][s.y1]=='#')
{
s.x1-=dx[i];s.y1-=dy[i];
}
if(s.x2<||s.x2>=n||s.y2<||s.y2>=m||maze[s.x2][s.y2]=='#')
{
s.x2-=dx[i];s.y2-=dy[i];
}
// printf("%d %d %d %d\n",s.x1,s.y1,s.x2,s.y2);
s.str=e.str+dir[i];
int h=hash1(s);
if(!st.count(h))
{
st.insert(h);
que.push(s);
}
}
}
} int main()
{
// freopen("data.txt","r",stdin);
// freopen("b.txt","w",stdout);
while(~scanf("%d%d",&n,&m))
{
point s;
s.x1=,s.y1=,s.x2=,s.y2=,s.str="";
for(int i=;i<n;i++)
{
scanf("%s",maze[i]);
for(int j=;j<m;j++)
{
if(maze[i][j]=='*')
{
if(s.x1==&&s.y1==)
{
s.x1=i;s.y1=j;
}
else
{
s.x2=i;s.y2=j;
}
}
}
}
// printf("%d %d %d %d\n",s.x1,s.y1,s.x2,s.y2);
flag=;
go="";
bfs(s);
if(!flag) cout<<"Sorry"<<endl;
else cout<<go<<endl;
}
return ;
}
hdu - 2216 Game III && xtu 1187 Double Maze (两个点的普通bfs)的更多相关文章
-
HDU 2216 Game III(BFS)
Game III Problem Description Zjt and Sara will take part in a game, named Game III. Zjt and Sara wil ...
-
hdu3713 Double Maze
Problem Description Unlike single maze, double maze requires a common sequence of commands to solve ...
-
hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)
了校赛,还有什么途径可以申请加入ACM校队? 覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K ...
-
java 金额计算,商业计算 double不精确问题 BigDecimal,Double保留两位小数方法
解决办法================== http://blog.javaxxz.com/?p=763 一提到Java里面的商业计算,我们都知道不能用float和double,因为他们无法 进行精 ...
-
hdu 4630 查询[L,R]区间内任意两个数的最大公约数
No Pain No Game Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
-
java使double保留两位小数的多方法
java使double保留两位小数的多方法 java保留两位小数 mport java.text.DecimalFormat; DecimalFormat df = new DecimalFormat ...
-
HDU 4048 Zhuge Liang&#39;s Stone Sentinel Maze
Zhuge Liang's Stone Sentinel Maze Time Limit: 10000/4000 MS (Java/Others) Memory Limit: 32768/327 ...
-
HDU 3277Marriage Match III(二分+并查集+拆点+网络流之最大流)
题目地址:HDU 3277 这题跟这题的上一版建图方法差点儿相同,仅仅只是须要拆点.这个点拆的也非常巧妙,既限制了流量,还仅仅限制了一部分,曾经一直以为拆点会所有限制,原来也能够用来分开限制,学习了. ...
-
hdu 2216 bfs
题目大意:两个东西朝相同方向移动Sample Input4 4XXXX.Z...XS.XXXX4 4XXXX.Z...X.SXXXX4 4XXXX.ZX..XS.XXXXSample Output11 ...
随机推荐
-
WebStorm phpStorm 注册码
WebStorm User or company Name: EMBRACE ===== LICENSE KEY===== 24718-12042010 00001h6wzKLpfo3gmjJ8xoT ...
-
zepto源码研究 - ajax.js(请求过程中的各个事件分析)
简要:ajax请求具有能够触发各类事件的功能,包括:触发全局事件,请求发送前事件,请求开始事件,请求结束事件等等,贯穿整个ajax请求过程,这是非常有用的,我们可以利用这些事件来做一些非常有意思的事情 ...
-
Using Sphinx to index CNS database
1, look at the sphinx.person.address.conf to see how to configure the conf file2, index the database ...
-
MQTT和paho(一)
参考链接:http://blog.csdn.net/yangzl2008/article/details/8861069 一.mqtt 1.简单介绍 http://mqtt.org/software ...
-
网站流量统计PV&;UV
统计网站pv和uv PV是网站分析的一个术语,用以衡量网站用户访问的网页的数量. 对于广告主,PV值可预期它可以带来多少广告收入.一般来说,PV与来访者的数量成正比,但是PV并不直接决定页面的真实来访 ...
-
面经 cisco 2
1. cpu中的cache结构及cache一致性 一. 引子 在多线程环境中,经常会有一些计数操作,用来统计线上服务的一些qps.平均延时.error等.为了完成这些统计,可以实现一个多线程环境下的计 ...
-
关于Tortoise git汉化包装了,不管用,仍然是英文菜单的问题记录
今天在装小乌龟(TortoiseGIT)碰到了安装中文语言包不管用的情况,后来在几番折腾之后总算搞定了,但是具体哪一步搞定的,目前原因还不清楚,所以把搞定的过程记录下,留作后用: 1.Tortoise ...
-
导航栏pop拦截
一.新建一个分类 二.导入分类头文件 三.需要拦截的地方实现方法 - (BOOL)navigationShouldPopTwo 即可 .h #import <UIKit/UIKit.h&g ...
-
基于Android的小巫新闻客户端开发系列教程
<ignore_js_op> 141224c6n6x7wmu1aacap7.jpg (27.51 KB, 下载次数: 0) 下载附件 保存到相册 23 秒前 上传 <ignor ...
-
Scala中使用implict 扩展现有类的方法
Scala中implict的一种用法就是扩展现有类的方法,有点类似于.Net中的扩展方法(MS对扩展方法的介绍:扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改 ...