您的位置:首页 > 其它

POJ 3009:Curling 2.0

2017-07-30 22:05 489 查看
问题描述

冰壶游戏2.0,冰壶可以在没有墙壁的路线上沿直线前进,遇到墙壁后停止并击碎面前的墙壁,求最短几步。

解题思路

DFS,但是每次进行完一条线路的计算之后要将击碎的墙壁还原。

代码

#include <iostream>
#include <stdio.h>

using namespace std;

int board[22][22];
int starti,startj;
int sum,ans;
int direct[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int w,h;

void dfs(int i,int j,int sum)
{
//十步以上直接返回
if(sum>10)
return;
//在四个方向上探索
for(int k=0;k<4;k++)
{
int nexti=i;
int nextj=j;
//如果前方是障碍物,则跳过此方向
if(board[nexti+direct[k][0]][nextj+direct[k][1]]==1)
continue;
//如果前方不是障碍物,则继续行走
while(board[nexti+direct[k][0]][nextj+direct[k][1]]==0)
{
nexti=nexti+direct[k][0];
nextj=nextj+direct[k][1];
}
//如果前方是障碍物
if(board[nexti+direct[k][0]][nextj+direct[k][1]]==1)
{
//击碎障碍物
board[nexti+direct[k][0]][nextj+direct[k][1]]=0;
//dfs
dfs(nexti,nextj,sum+1);
//还原障碍物
board[nexti+direct[k][0]][nextj+direct[k][1]]=1;
}
//如果到达终点,且是当前最小步数,则保存
if(board[nexti+direct[k][0]][nextj+direct[k][1]]==3)
if(sum<ans)
ans=sum;
}
}

int main()
{
while(cin>>w>>h)
{
if((w==0)&&(h==0))
break;
ans=100;
//方便处理越界的情况
for(int i=0;i<=h+1;i++)
for(int j=0;j<=w+1;j++)
board[i][j]=-1;
for(int i=1;i<=h;i++)
for(int j=1;j<=w;j++)
{
cin>>board[i][j];
if(board[i][j]==2)
{
starti=i;
startj=j;
board[i][j]=0;
}
}
dfs(starti,startj,1);
if(ans>10)
ans=-1;
cout<<ans<<endl;
}
return 0;
}

问题与反思
1.刚开始的时候没有使用方向向量,导致代码冗长,以后学会了使用方向向量;

2.刚开始的时候思路混乱,判断的顺序出现了问题,导致一直死循环,借鉴了别人的代码才理清思路;

3.开始时没有想到全局变量,对于最少步数的保存写的特别混乱;

3.觉得还可以剪枝,过来时的方向在下一次计算时应该可以跳过, 但是AC之后也没有再去验证。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DFS