POJ3009 - Curling 2.0 - DFS+方向直线移动


题意

给出一个 \(m\) x \(n\) 的图,图中有 \(1\)\(2\)\(3\)\(4\)数字,分别表示: \(0\) 空地、 \(1\) 障碍物、 \(2\) 起点、 \(3\) 终点。

让我们输出:从起点( \(S\) )到终点( \(G\) )的最小步数,无法达到输出 \(-1\)

要求:

  1. 仅限 \(x\)\(y\) 方向(即禁止对角线移动)。

  2. 石头一旦开始移动,只能沿着这一个方向一直移动,除非下列任一事件发生:

    • 石头击中黑色方块。

    • 石块飞出游戏板之外(即超出图的边界)。

    • 石头停在他击中的砖块之前被击中的砖块消失(也就是说,如果石头走到障碍物的四周,那么可以换方向走,该障碍物消失变成空地 \(0\))。

  3. 步数不能超过 \(10\) 步。

思路

正确的思路是:先找到起点 \(S\) ,然后将该点由 \(2\) 变为 \(0\) ,表示是空地,可以走(本来也可以走)。

然后开始从 \(S\) 开始搜,

关键点主要是:不一次一格走,而是一次一条线走,该如何写?其实通过一个while和一个方向累加就行了,

while(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]==0)
            tx+=to[i][0],ty+=to[i][1];

之后如果碰到终点了,那么直接 更新+return 就行了。

排除所有碰到终点呀、越界呀这些情况,最后开始继续往下搜,首先把障碍物消除,变为空地 \(0\) ,搜索,把障碍物还原变为 \(1\)
其实我的思路是BFS,因为求最小步数嘛,但是我不会写……

这是我写的BFS部分代码:

#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define inf 03f3f3f3f

char s[22][22];
int n,m,s,t,ss,tt;
bool book[22][22];
int to[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
typedef pairP;

int bfs()
{
    memset(dis,inf,sizeof(dis));
    dis[s][t]=0;
    queue

Q; Q.push(P(s,t)); while(!Q.empty()) { P x=Q.front(); Q.pop(); if(x.first==ss&&x.second==tt) break; for(int i=0;i<4;i++) { int tx=x.first+to[i][0]; int ty=x.second +to[i][1]; if(tx>=0&&tx=0&&ty>m>>n) { if(m==0&&n==0) break; for(int i=0;i

AC代码

#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f

int a[22][22],n,m,s,t,ss,tt,ans;
bool book[22][22];
int to[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
typedef pairP;

void dfs(int x,int y,int step)
{
    if(step>=ans||step>=10) return ;
    for(int i=0;i<4;i++)
    {
        int tx=x+to[i][0];
        int ty=y+to[i][1];
        if(a[tx][ty]==1) // 遇到障碍物
            continue ;
        while(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]==0)
            tx+=to[i][0],ty+=to[i][1];
        if(tx>=1&&tx<=n&&ty>=1&&ty<=m)
        {
            if(a[tx][ty]==3) // 0空地、1障碍物、2起点、3终点
            {
                ans=step+1;
                return ;
            }
            a[tx][ty]=0; //消去障碍物
            dfs(tx-to[i][0],ty-to[i][1],step+1);
            a[tx][ty]=1;
        }
    }
}

int main()
{
	while(cin>>m>>n)
	{
	    if(m==0&&n==0) 
	        break;
	    //0空地、1障碍物、2起点、3终点
	    ans=inf;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>a[i][j];
                if(a[i][j]==2)
                    a[i][j]=0,s=i,t=j;
            }
        }
        dfs(s,t,0);
        if(ans!=inf)
            cout<