hdu - 2216 Game III && xtu 1187 Double Maze (两个点的普通bfs)
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'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 ...
随机推荐
- EF 更新条目时出错。有关详细信息,请参见内部异常。
现象:使用EF新增记录时,一直报上述异常,网上说是值为空.主键外键未设等原因导致,但是改正这些情况下问题依然 解决过程:异常中有一句(请参见内部异常),一直都没有当回事,后来实在没办法就静下心来看了看 ...
- Entity Framework公共的增删改方法
using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.I ...
- NYOJ-206 矩形的个数 AC 分类: NYOJ 2013-12-29 22:19 265人阅读 评论(0) 收藏
这题目是小学奥数题目,方法可以百度到,但是,有个难点就是,数据类型大小不够,如果是1000x1000的矩阵,那么就会超过int的范围,所以,就引进了long long的数据类型 #include< ...
- 2014 ACM/ICPC Asia Regional Guangzhou Online
Wang Xifeng's Little Plot http://acm.hdu.edu.cn/showproblem.php?pid=5024 预处理出每个点八个方向能走的最远距离,然后枚举起点,枚 ...
- [工作积累] error: bad class file magic (cafebabe) or version (0033.0000)
Update Android SDK build tool to latest can solve my problem.
- HDU1014Uniform Generator
Uniform Generator Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- 分布式数据存储 - MySQL双主复制
上篇文章<分布式数据存储 - MySQL主从复制>,我们说到MySQL主从复制很好的保障了从库,读的高可用性.so,问题来了: 1.针对主库,写的高可用性又是如何做到高可用性? 2.如果需 ...
- UITextField中文搜索
导入头文件 #import "ChineseInclude.h"#import "PinYinForObjc.h" NSMutableArray *search ...
- C++堆栈与函数调用
一.C++程序内存分配 1)在栈上创建.在执行函数时,函数内局部变量的存储单元都在栈上创建,函数结束是,这些存储单元自动被释放.栈内存的分配运算内置于处理器的指令集中,一般采用寄存器来存取,效率很高但 ...
- mvc5 错误页如何定义
项目根目录下的Web.config <system.web> <customErrors mode="On" defaultRedirect="~/Er ...