您的位置:首页 > 其它

poj3009 Curling 2.0(DFS回溯)

2015-06-04 18:52 288 查看
题目大意是:给你一个球,刚开始是静止的,可以通过触碰给他一个初速度,一旦球运动起来就不会停止,除非遇到一个石头。遇到石头以后小球就原地停止了,然后石头就被砸碎了。小球越界就算失败了。问你最少进行多少次操作,可以让小球到达终点。题中还有一个要求,如果超过10步,就算失败了。

这道题目做了好久啊。可能方法太麻烦了。

#include<stdio.h>
#include<string.h>
int map[105][105],si,sj,ei,ej,w,h; //1 right    2 down    3 left   4 up
int flag,t,dir[4][2]={0,1,1,0,0,-1,-1,0},mini;
int check(int x,int y)
{
if(x<=0||y<=0||x>h||y>w)return 0;
return 1;
}
void dfs(int x,int y,int cnt,int turn,int speed)   //x,y代表小球的坐标,cnt代表当前操作次数,turn代表方向,speed判断小球状态
{

if(check(x,y)==0){flag=1;return;}  //判断是否越界。
if(x==ei&&y==ej){
if(mini>cnt)mini=cnt;
flag=1;t=cnt;return;
}

if(cnt>10)return;
if(speed==0){     //如果小球静止,就对4个方向进行搜索。
for(int i=0;i<4;i++)
{
int fx=x+dir[i][0];
int fy=y+dir[i][1];
if(map[fx][fy]==1)      //如果周围是石头就跳过
continue;
dfs(fx,fy,cnt+1,i+1,1);
}

}
else {              //如果小球在运动,就按原方向搜索
if(turn==1)
{
if(map[x][y+1]==1)
{
map[x][y+1]=0;
dfs(x,y,cnt,1,0);
map[x][y+1]=1;      .//回溯
}
else dfs(x,y+1,cnt,1,1);
}
if(turn==2){
if(map[x+1][y]==1)
{
map[x+1][y]=0;
dfs(x,y,cnt,2,0);
map[x+1][y]=1;
}
else dfs(x+1,y,cnt,2,1);
}
if(turn==3){
if(map[x][y-1]==1)
{
map[x][y-1]=0;
dfs(x,y,cnt,3,0);
map[x][y-1]=1;
}
else dfs(x,y-1,cnt,3,1);
}
if(turn==4){
if(map[x-1][y]==1)
{
map[x-1][y]=0;
dfs(x,y,cnt,4,0);
map[x-1][y]=1;
}
else dfs(x-1,y,cnt,4,1);
}
}
if(flag&&speed)return;     //这里判断越界以后的状态,因为越界以后回到上一个位置,这时判断小球的状态,如果是静止的,就继续进行搜索。如果是运动的,继续返回(因为小球在一条线上运动时不能自己停止)
else if(flag&&speed==0)flag=0;
}
int main()
{
int i,j,k;
while(scanf("%d%d",&w,&h)!=EOF)
{

if(w==0&&h==0)break;
memset(map,0,sizeof(map));    //注意要对迷宫进行初始化
flag=0;
mini=99999999;
for(i=1;i<=h;i++)
for(j=1;j<=w;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==2){
si=i;sj=j;
}
if(map[i][j]==3){
ei=i;ej=j;
}
}
dfs(si,sj,0,1,0);
if(mini<99999999)
printf("%d\n",mini);
else printf("-1\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: