DFS专攻:HDU 1010(DFS+奇偶剪枝)

来源:互联网 发布:javascript正则表达式= 编辑:程序博客网 时间:2024/05/19 12:11

这题有点脑人滴,因为好久不练习DFS了,几乎不会做了,所以要专攻一下才行。直接写的DFS超时了两发,唉,不得已看了别人的,然后别人都是奇偶剪枝,以前没有学过这个,不知道剪枝是啥意思。然后又多看了几个人的博客,别人写得不清不楚,也没看明白是啥意思。然后直接百度百科……没想到里面真是想得好清楚,彻底理解奇偶剪枝是什么回事了!

奇偶剪枝百度百科学习网站:http://baike.baidu.com/link?url=4GHqaNcncZrCnBnjYPOBg66lQ68HcSajeAro7_QVfDX3lyED_MyfNwc0MqxoOO3eIbWIMeWfU6k0UAr2U1ZvCq

这周专攻的第一道DFS终于领会了……继续努力!

剪枝的目的就是要省时……

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<cmath>#include<set>#include<vector>#include<stack>#include<ctime>#include<cstdlib>#define mem(a,b) memset(a,b,sizeof(a))typedef long long ll;using namespace std;int n,m,t,xx,yy,k,d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};char map[10][10];void dfs(int x,int y,int tt){    if(k) return;  //如果前面已经有符合的话就不用再往下判断了    if(tt==t)    {        if(xx==x&&yy==y) {k=1;return;}        return;    }    int tem=abs(x-xx)+abs(y-yy)-abs(tt-t);  //所走步数与奇偶剪枝的判断式    if(tem>0||tem&1) return;  //步长如果大于剩余的步长肯定不会在特定的步数走到啦;然后奇数的剪掉。    for(int i=0;i<4;i++)    {        int x2=x+d[i][0];        int y2=y+d[i][1];        if(x2>=0&&x2<n&&y2>=0&&y2<m&&map[x2][y2]!='X')        {            map[x2][y2]='X';   //走的过程可能回到这点,所以先变成墙            dfs(x2,y2,tt+1);            map[x2][y2]='.';   //回溯        }    }}int main(){    int i,j,x,y;    while(scanf("%d%d%d",&n,&m,&t)&&(n||m||t))    {        int w=0;        for(i=0;i<n;i++)        {            scanf("%s",map[i]);            for(j=0;j<m;j++)            {                if(map[i][j]=='S') {x=i;y=j;}                else if(map[i][j]=='D') {xx=i;yy=j;}                else if(map[i][j]=='X') w++;            }        }        if(m*n-w<=t) {printf("NO\n");continue;}  //如果可以走的块数比t还小,那这种情况也肯定不行        k=0;        map[x][y]='X';        dfs(x,y,0);        if(k) printf("YES\n");        else printf("NO\n");    }    return 0;}