hdu 3309 Roll The Cube(bfs)
2015-08-11 23:46
405 查看
Problem Description
This is a simple game.The goal of the game is to roll two balls to two holes each.
'B' -- ball
'H' -- hole
'.' -- land
'*' -- wall
Remember when a ball rolls into a hole, they(the ball and the hole) disappeared, that is , 'H' + 'B' = '.'.
Now you are controlling two balls at the same time.Up, down , left , right --- once one of these keys is pressed, balls exist roll to that direction, for example , you pressed up , two balls both roll up.
A ball will stay where it is if its next point is a wall, and balls can't be overlap.
Your code should give the minimun times you press the keys to achieve the goal.
Input
First there's an integer T(T<=100) indicating the case number.
Then T blocks , each block has two integers n , m (n , m <= 22) indicating size of the map.
Then n lines each with m characters.
There'll always be two balls(B) and two holes(H) in a map.
The boundary of the map is always walls(*).
Output
The minimum times you press to achieve the goal.
Tell me "Sorry , sir , my poor program fails to get an answer." if you can never achieve the goal.
Sample Input
Sample Output
题意:同时控制两个球,把他们移动到洞里 ,球是同时运动的,当一个球到洞了后,另一个球可以从这里经过。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace
std;
int dir[4][2] = {0,1,1,0,0,-1,-1,0};
char map[24][24];
bool vis[24][24][24][24];
int n,m;
struct node
{
int x[2],y[2]; //两个球坐标
bool ball[2]; //球的状态
bool hole[2]; //洞的状态
int step;
node()
{
ball[0]=ball[1]=hole[0]=hole[1]=false;
step=0;
}
void init()
{
ball[0]=ball[1]=hole[0]=hole[1]=false;
step=0;
}
};
node start;
bool check(node &a)
{
for (int i=0; i<2; i++)
{
if(a.x[i]<0 ||a.x[i]>=n || a.y[i]<0
|| a.y[i]>=m)
return
false;
}
if(a.x[0]==a.x[1]&& a.y[0]==a.y[1]
&& a.ball[0]==a.ball[1] && a.ball[0]==0)
return
false;
if(vis[a.x[0]][a.y[0]][a.x[1]][a.y[1]])
return
false;
return
true;
}
int bfs()
{
memset(vis,0,
sizeof(vis));
queue<node>q;
q.push(start);
vis[start.x[0]][start.y[0]][start.x[1]][start.y[1]]=true;
node temp;
while (!q.empty())
{
start=q.front();
q.pop();
for (int i=0; i<4; i++)
{
temp=start;
temp.step++;
for (int j=0; j<2; j++)//对两个球进行移动
{
if(!temp.ball[j])
{
temp.x[j]+=dir[i][0];
temp.y[j]+=dir[i][1];
if(map[temp.x[j]][temp.y[j]]=='*')
{
temp.x[j]-=dir[i][0];
temp.y[j]-=dir[i][1];
}
}
}
if(check(temp))
{
vis[temp.x[0]][temp.y[0]][temp.x[1]][temp.y[1]]=true;
bool flag=true;
for (int j=0; j<2; j++) //检查球是否进洞
{
int k=map[temp.x[j]][temp.y[j]]; //判断第k个洞的状态
if(k<2 && !temp.hole[k])
{
temp.hole[k]=1;
temp.ball[j]=1;
}
if(!temp.ball[j])
flag=false;
}
if(flag)
//都进洞了
return temp.step;
q.push(temp);
}
}
}
return -1;
}
int main()
{
int t,cnt;
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
getchar();
cnt=0;
bool flag=false;
for (int i=0; i<n; i++)
{
for (int j=0; j<m; j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='B' && !flag)
{
start.x[0]=i;
start.y[0]=j;
flag=true;
}
else
if(map[i][j]=='B' && flag)
{
start.x[1]=i;
start.y[1]=j;
}
if(map[i][j]=='H')
{
map[i][j]=cnt++;
}
}
getchar();
}
start.init();
int ans=bfs();
if(ans!=-1)
printf("%d\n",ans);
else
printf("Sorry , sir , my poor program fails to get an answer.\n");
}
return 0;
}
This is a simple game.The goal of the game is to roll two balls to two holes each.
'B' -- ball
'H' -- hole
'.' -- land
'*' -- wall
Remember when a ball rolls into a hole, they(the ball and the hole) disappeared, that is , 'H' + 'B' = '.'.
Now you are controlling two balls at the same time.Up, down , left , right --- once one of these keys is pressed, balls exist roll to that direction, for example , you pressed up , two balls both roll up.
A ball will stay where it is if its next point is a wall, and balls can't be overlap.
Your code should give the minimun times you press the keys to achieve the goal.
Input
First there's an integer T(T<=100) indicating the case number.
Then T blocks , each block has two integers n , m (n , m <= 22) indicating size of the map.
Then n lines each with m characters.
There'll always be two balls(B) and two holes(H) in a map.
The boundary of the map is always walls(*).
Output
The minimum times you press to achieve the goal.
Tell me "Sorry , sir , my poor program fails to get an answer." if you can never achieve the goal.
Sample Input
4 6 3 *** *B* *B* *H* *H* *** 4 4 **** *BB* *HH* **** 4 4 **** *BH* *HB* **** 5 6 ****** *.BB** *.H*H* *..*.* ******
Sample Output
3 1 2 Sorry , sir , my poor program fails to get an answer.
题意:同时控制两个球,把他们移动到洞里 ,球是同时运动的,当一个球到洞了后,另一个球可以从这里经过。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace
std;
int dir[4][2] = {0,1,1,0,0,-1,-1,0};
char map[24][24];
bool vis[24][24][24][24];
int n,m;
struct node
{
int x[2],y[2]; //两个球坐标
bool ball[2]; //球的状态
bool hole[2]; //洞的状态
int step;
node()
{
ball[0]=ball[1]=hole[0]=hole[1]=false;
step=0;
}
void init()
{
ball[0]=ball[1]=hole[0]=hole[1]=false;
step=0;
}
};
node start;
bool check(node &a)
{
for (int i=0; i<2; i++)
{
if(a.x[i]<0 ||a.x[i]>=n || a.y[i]<0
|| a.y[i]>=m)
return
false;
}
if(a.x[0]==a.x[1]&& a.y[0]==a.y[1]
&& a.ball[0]==a.ball[1] && a.ball[0]==0)
return
false;
if(vis[a.x[0]][a.y[0]][a.x[1]][a.y[1]])
return
false;
return
true;
}
int bfs()
{
memset(vis,0,
sizeof(vis));
queue<node>q;
q.push(start);
vis[start.x[0]][start.y[0]][start.x[1]][start.y[1]]=true;
node temp;
while (!q.empty())
{
start=q.front();
q.pop();
for (int i=0; i<4; i++)
{
temp=start;
temp.step++;
for (int j=0; j<2; j++)//对两个球进行移动
{
if(!temp.ball[j])
{
temp.x[j]+=dir[i][0];
temp.y[j]+=dir[i][1];
if(map[temp.x[j]][temp.y[j]]=='*')
{
temp.x[j]-=dir[i][0];
temp.y[j]-=dir[i][1];
}
}
}
if(check(temp))
{
vis[temp.x[0]][temp.y[0]][temp.x[1]][temp.y[1]]=true;
bool flag=true;
for (int j=0; j<2; j++) //检查球是否进洞
{
int k=map[temp.x[j]][temp.y[j]]; //判断第k个洞的状态
if(k<2 && !temp.hole[k])
{
temp.hole[k]=1;
temp.ball[j]=1;
}
if(!temp.ball[j])
flag=false;
}
if(flag)
//都进洞了
return temp.step;
q.push(temp);
}
}
}
return -1;
}
int main()
{
int t,cnt;
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
getchar();
cnt=0;
bool flag=false;
for (int i=0; i<n; i++)
{
for (int j=0; j<m; j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='B' && !flag)
{
start.x[0]=i;
start.y[0]=j;
flag=true;
}
else
if(map[i][j]=='B' && flag)
{
start.x[1]=i;
start.y[1]=j;
}
if(map[i][j]=='H')
{
map[i][j]=cnt++;
}
}
getchar();
}
start.init();
int ans=bfs();
if(ans!=-1)
printf("%d\n",ans);
else
printf("Sorry , sir , my poor program fails to get an answer.\n");
}
return 0;
}
相关文章推荐
- 如果牛顿是程序员,那么?
- AC自动机模板
- 在活动中使用menu
- POJ 3468 Simple Problem with Integers
- ios单元测试之GHUnit
- Gevent 资料整理
- 前端面经系列(二)
- Gray code(hdu5375+异或二进制的规律)
- 单点登录(跨域)
- light oj 1066- Gathering Food (bfs)
- [问与答]怎样在 Android Stuido中删除一个project
- Cookie深度解析
- 黑马程序员——面向对象(上)— 类、对象、封装、继承、构造方法
- [问与答]怎样在 Android Stuido中删除一个project
- CodeForces 344
- ios的单元测试OCUnit以及更新了之后的XCTestCase
- svn冲突解决
- 有两部智能手机-怎么录屏
- ACM的奇计淫巧_扩栈C++/G++
- POJ 2007 Scrambled Polygon(凸包)