poj3009 Curling 2.0 DFS搜索

On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat different from ours. The game is played on an ice game board on which a square mesh is marked. They use only a single stone. The purpose of the game is to lead the stone from the start to the goal with the minimum number of moves.

Fig. 1 shows an example of a game board. Some squares may be occupied with blocks. There are two special squares namely the start and the goal, which are not occupied with blocks. (These two squares are distinct.) Once the stone begins to move, it will proceed until it hits a block. In order to bring the stone to the goal, you may have to stop the stone by hitting it against a block, and throw again.

題意:好難看懂。。還是找的翻譯。

題目說的是一種冰壺的遊戲,起點在2,終點在3,1是牆,0是滑動區域。

就是要求把一個冰壺從起點“2”用最少的步數移動到終點“3”

其中0爲移動區域,1爲石頭區域,冰壺一旦想着某個方向運動就不會停止,也不會改變方向(想想冰壺在冰上滑動),除非冰壺撞到石頭1 或者 到達終點 3

要注意的是:

冰壺撞到石頭後,冰壺會停在石頭前面,此時(靜止狀態)才允許改變冰壺的運動方向,而該塊石頭會破裂,石頭所在的區域由1變爲0. 也就是說,冰壺撞到石頭後,並不會取代石頭的位置。

終點是一個摩擦力很大的區域,冰壺若到達終點3,就會停止在終點的位置不再移動。

題解:從起點開始搜索第一個0,也就是可以滑動的地方,然後開始用DFS搜索,因爲冰壺是遇到牆纔會停止,那麼就只有兩種可能,一種是碰到牆,一種是跑出去了,這種情況要換個方向重新搜索,一直走到碰到牆的時候,就把牆“1”變成“0”,然後在遇到牆的上一個地方DFS搜索。這樣就可以找到最少的時間到達3終點。

#include<iostream>
#include<cstring>
using namespace std;
int n,m;
int a[105][105];
int ex,ey,sx,sy,sum;
int f[4][2]={0,1,1,0,0,-1,-1,0};
void dfs(int x,int y,int num)
{
    if(num>10)
        return ;
    int flag;
    for(int i=0;i<4;i++)
    {
        flag=0;
        int nx=x+f[i][0];
        int ny=y+f[i][1];
        if(a[nx][ny]==1)//找到第一個可以滑動的區域。
            continue;
            nx=x;
            ny=y;//要直線運動直到撞牆,所以把x,y賦值。
        while(1)
        {
            nx=nx+f[i][0];
            ny=ny+f[i][1];
            if(nx>0&&ny>0&&nx<=m&&ny<=n)
            {
                if(a[nx][ny]==3)
                {
                    if(sum>num)
                        sum=num;
                    return ;
                }
                else if(a[nx][ny]==1)
                {
                    break;
                }
            }
            else//出界了就繼續換個方向搜索。
            {
                flag=1;
                break;
            }
        }
        if(flag)
            continue;
        else
        {
            a[nx][ny]=0;
            dfs(nx-f[i][0],ny-f[i][1],num+1);
            a[nx][ny]=1;
        }
    }
}
int main()
{
    while(cin>>n>>m)
    {
        if(n==0&&m==0)
            break;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
            if(a[i][j]==2)
            {
                ex=i,ey=j;
            }
            if(a[i][j]==3)
                sx=i,sy=j;
        }
        sum=0x3f3f3f;//因爲是計算最小的,所以初始設爲INF。
        dfs(ex,ey,1);
        if(sum==0x3f3f3f)
            cout<<"-1"<<endl;
        else
            cout<<sum<<endl;
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章