【剪枝】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;
}



原文地址:https://www.cnblogs.com/javawebsoa/p/3233932.html