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)的更多相关文章

  1. 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 ...

  2. hdu3713 Double Maze

    Problem Description Unlike single maze, double maze requires a common sequence of commands to solve ...

  3. hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)

    了校赛,还有什么途径可以申请加入ACM校队?  覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  4. java 金额计算,商业计算 double不精确问题 BigDecimal,Double保留两位小数方法

    解决办法================== http://blog.javaxxz.com/?p=763 一提到Java里面的商业计算,我们都知道不能用float和double,因为他们无法 进行精 ...

  5. hdu 4630 查询[L,R]区间内任意两个数的最大公约数

    No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. java使double保留两位小数的多方法

    java使double保留两位小数的多方法 java保留两位小数 mport java.text.DecimalFormat; DecimalFormat df = new DecimalFormat ...

  7. 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 ...

  8. HDU 3277Marriage Match III(二分+并查集+拆点+网络流之最大流)

    题目地址:HDU 3277 这题跟这题的上一版建图方法差点儿相同,仅仅只是须要拆点.这个点拆的也非常巧妙,既限制了流量,还仅仅限制了一部分,曾经一直以为拆点会所有限制,原来也能够用来分开限制,学习了. ...

  9. hdu 2216 bfs

    题目大意:两个东西朝相同方向移动Sample Input4 4XXXX.Z...XS.XXXX4 4XXXX.Z...X.SXXXX4 4XXXX.ZX..XS.XXXXSample Output11 ...

随机推荐

  1. 剑指offer-17题

    题目要求:输入一个表示整数的字符串,把该字符串转换成整数并输出.例如输入字符串"345",则输出整数345. 分析:这道题能够很好地反应出程序员的思维和编程习惯. 的确,自己编写的 ...

  2. MSDN:Code First 迁移

    来自:MSDN:Code First 迁移,完全照搬! 本演练将提供对实体框架中 Code First 迁移的概述.您可以完成整个演练,也可以跳至自己感兴趣的主题.主题如下: 启用迁移 生成并运行迁移 ...

  3. 引擎设计跟踪(九.14.2c) 最近一些小的更新

    1. bump map与normal map 昨天拿了crytek sponza(http://www.crytek.com/cryengine/cryengine3/downloads)场景测试, ...

  4. PowerDesigner(九)-模型文档编辑器(生成项目文档)(转)

    模型文档编辑器 PowerDesigner的模型文档(Model  Report)是基于模型的,面向项目的概览文档,提供了灵活,丰富的模型文档编辑界面,实现了设计,修改和输出模型文档的全过程. 模型文 ...

  5. 【Asp.Net WebFrom】分页

    Asp.Net WebForm 分页 一. 前言 Asp.Net WebForm 内置的DataPager让人十分蛋疼 本文使用的分页控件是第三方分页控件 AspNetPager,下载地址: 链接: ...

  6. Shell日期时间和时间戳的转换

    Gitlab的备份文件是以时间戳显示的,类似:1438624820_gitlab_backup.tar 为了更易于阅读,想把文件名转换成日期格式:2015-08-04_gitlab_backup.ta ...

  7. 全自动化的 Android 编译管线

    [编者按]Nicolas Frankel 是 hybris 的高级顾问, 在Java / J2EE 领域拥有超过10年的管理经验,本文阐述了他在使用自动化工序去构建 Android 应用程序遇到的一些 ...

  8. VC中Source Files, Header Files, Resource Files,External Dependencies的区别

    VC中Source Files, Header Files, Resource Files,External Dependencies的区别 区别: Source Files 放源文件(.c..cpp ...

  9. ASP.NET 将Excel导入数据库

    将Excel导入数据库大致流程:  Excel数据->DataSet->数据库 需要做的准备:1.FileUpload控件一个,按钮一个,如果需要即时显示那么GridView或DataGr ...

  10. HDU 1028 Ignatius and the Princess III (递归,dp)

    以下引用部分全都来自:http://blog.csdn.net/ice_crazy/article/details/7478802  Ice—Crazy的专栏 分析: HDU 1028 摘: 本题的意 ...