【剪枝】HDU 1010——tempter of the bone

来源:点击打开链接

看上去数据规模很小,但是必须要剪枝,否则直接爆TLE。

通过这个题可以练习奇偶剪枝。

另外:还有一个优化方式,如果所有步数走完了门还没关,则直接返回结果"NO".

 

#include <iostream>

#include <cstring>

#include <cmath>

#include <cstdlib>

using namespace std;



int n,m,tarstep;

int tari,tarj;

int si,sj;

char map[10][10];

int dir[4][2]={0,1,0,-1,1,0,-1,0};

int ok=0;



void dfs(int si,int sj,int step)

{

    int temp;

    if(si>n || sj>m || si<=0 || sj<=0)

        return;

    if(step==tarstep && si==tari && sj==tarj)

        ok=1;

    if(ok==1)

        return;

     //奇偶剪枝

    temp=(tarstep-step)-abs(si-tari)-abs(sj-tarj);

    if(temp<0 || temp&1)

        return;

    for(int i=0;i<4;i++)

    {

        if(map[si+dir[i][0]][sj+dir[i][1]]!='X')

        {

            map[si+dir[i][0]][sj+dir[i][1]]='X';

            dfs(si+dir[i][0],sj+dir[i][1],step+1);

            map[si+dir[i][0]][sj+dir[i][1]]='.';

        }

    }

    return ;

}



int main()

{

    while(cin>>n>>m>>tarstep)

    {

        if(n==0 && m==0 && tarstep==0)

            break;

        int wall=0;

        for(int i=1;i<=n;i++)  //下标从1开始

        {

            for(int j=1;j<=m;j++)

            {

                cin>>map[i][j];

                if(map[i][j]=='S')

                {

                    si=i;

                    sj=j;

                }

                else if(map[i][j]=='D')

                {

                    tari=i;

                    tarj=j;

                }

                else if(map[i][j]=='X')

                    wall++;

            }



        }

        if(n*m-wall<tarstep) //剪枝,如果能走的空地走完门没开

        {

            cout<<"NO"<<endl;

            continue;

        }

        ok=0;

        map[si][sj]='X'; //初始化破坏掉

        dfs(si,sj,0);

        if(ok==0)

        {

            cout<<"NO"<<endl;

        }

        else

        {

            cout<<"YES"<<endl;

        }



    }

    return 0;

}


 


 

你可能感兴趣的:(HDU)