hdu1010 DFS和剪枝

来源:互联网 发布:大型网页游戏源码 编辑:程序博客网 时间:2024/04/30 01:38


不剪枝的话会超时。。

#include <iostream>#include <cmath>#include<cstdio>using namespace std;int N, M ,T;char map[10][10];int dx,dy;bool can;int dir[4][2] = {{0,-1},                {0,1},                {1,0},                {-1,0}                };void dfs(int x,int y,int t){    //if(x < 0 || y< 0 || x >= N || y >= M)return;//越界则返回  也可以不判断 因为在进行dfs之前都确定了是不会越界的数    if(T == t && x == dx && y ==dy)//找到出口则返回    {        can = true;        return;    }    for(int i = 0;i < 4;i++)//四个方向分别进行搜索    {        int a ,b;        a = x + dir[i][0];        b = y + dir[i][1];        if(map[a][b] != 'X' && a>= 0 && a < N && b >= 0 && b < M)//这里已经判断了是否会越界        {            map[a][b] = 'X';//把当前要走的下一个点标记为不可走的点 因为已经走过的点是不能在走的            dfs(a,b,t + 1);//按照dir中的方向继续递归下去            if(can)return;//找到出路了            map[a][b] = '.';//回朔回去        }    }    return;}int main(){    int dot,sx,sy;//    freopen("data.txt","r",stdin);//    freopen("out.txt","w",stdout);    while(cin>>N>>M>>T,N||M||T)    {        dot = 0;        for(int i = 0; i < N; i++)            for(int j = 0; j < M; j++)            {                cin>>map[i][j];                if(map[i][j] == 'S')                {                    sx = i;                    sy = j;                }                else if(map[i][j] == 'D')                {                    dx = i;                    dy = j;                }                else if(map[i][j] == '.')dot++;            }        if(T > dot)        {        cout<<"NO"<<endl;        continue;        }        can = false;//对于很多数据的输入 最好不要在变量声明的时候付初值 经常忘了再新的测试数据前初始化。。。       map[sx][sy] = 'X';//从起点开始走 并把已经走过的起点标记为不可走     dfs(sx,sy,0);//走的步数t从0开始计数    if(can)cout<<"YES"<<endl;        else cout<<"NO"<<endl;        }//    fclose(stdin);//    fclose(stdout);    return 0;}



加上剪枝以后是这样的

   #include <iostream>#include <cmath>#include<cstdio>#include<cstdlib>using namespace std;int N, M ,T;char map[10][10];int dx,dy;bool can;int dir[4][2] = {{0,-1},                {0,1},                {1,0},                {-1,0}                };void dfs(int x,int y,int t){    //if(x < 0 || y< 0 || x >= N || y >= M)return;//越界则返回  也可以不判断 因为在进行dfs之前都确定了是不会越界的数    if(T == t && x == dx && y ==dy)//找到出口则返回    {        can = true;        return;    }    //if((T -t) % 2 != (abs(dx - x) + abs(dy - y)) % 2)return;    int tem ;    tem = (T - t) - abs((dx - x)) - abs((dy - y));//剩余时间 减去还需要走的步数 不够的话肯定到不了    if(tem < 0 || tem % 2 != 0)return;//tem &1是奇偶判断 如果剩余时间 和要走的步数同奇偶的话 就有可能到达 //不同奇偶的话 一定到不了 可以参考下面的 ppt 就知道为什么了//另外 a b同奇偶 则 a - b 比为偶数 否则为奇数    for(int i = 0;i < 4;i++)//四个方向分别进行搜索    {        int a ,b;        a = x + dir[i][0];        b = y + dir[i][1];        if(map[a][b] != 'X' && a>= 0 && a < N && b >= 0 && b < M)//这里已经判断了是否会越界        {            map[a][b] = 'X';//把当前要走的下一个点标记为不可走的点 因为已经走过的点是不能在走的            dfs(a,b,t + 1);//按照dir中的方向继续递归下去            if(can)return;//找到出路了            map[a][b] = '.';//回朔回去        }    }    return;}int main(){    int dot,sx,sy;//    freopen("data.txt","r",stdin);//    freopen("out.txt","w",stdout);    while(cin>>N>>M>>T,N||M||T)    {        dot = 0;        for(int i = 0; i < N; i++)            for(int j = 0; j < M; j++)            {                cin>>map[i][j];                if(map[i][j] == 'S')                {                    sx = i;                    sy = j;                }                else if(map[i][j] == 'D')                {                    dx = i;                    dy = j;                    dot++;//忘了再这里加一 总是WA 哎 因为最后一个D 也要走一步才能到                }                else if(map[i][j] == '.')dot++;            }        if(T > dot)        {        cout<<"NO"<<endl;        continue;        }        can = false;//对于很多数据的输入 最好不要在变量声明的时候付初值 经常忘了再新的测试数据前初始化。。。       map[sx][sy] = 'X';//从起点开始走 并把已经走过的起点标记为不可走     dfs(sx,sy,0);//走的步数t从0开始计数    if(can)        cout<<"YES"<<endl;    else        cout<<"NO"<<endl;    }//    fclose(stdin);//    fclose(stdout);    return 0;}

感受了一下DFS

主要在  数据初始化  和 dot 加一那个地方检查了很久才发现。。。尴尬

方向数组只要四个方向走到了就可以 不用在意顺序 顺序有时候会影响执行时间 但总体上应该不会超时吧

参考PPT19页

参考博客 1 2 3 4

0 0
原创粉丝点击