• HDU 1010


    题意:一只狗(柴犬,看到一块骨头,迷失在了maze里,S是起点,D是终点,问你能不能在时间T时从起点到达终点.

    这题有个小trick: 奇偶剪枝+普通剪枝

    解释一下:

    普通剪枝:从S到D要走的步数是k=abs(x1-x2)+abs(y1-y2);那么如果k>=T,永远不可能到达;

    奇偶剪枝:

    首先,分析一下两个坐标的奇偶性与K的关系

    当坐标是奇数的时候: x,y一定是一奇一偶的关系(妈哒输入法好难用

    当坐标是偶数的时候:x,y一定全为奇数或者全为偶数.

    当两个坐标奇偶性一样的时候:

    1.全为奇数,那么K=(奇数-奇数)+(偶数-偶数)或者K=(奇数-偶数)+(偶数-奇数);

    众所周知:

    奇数+/-奇数=偶数;

    偶数+/-偶数=偶数;

    奇数+/-偶数=奇数;

    妈哒这些数数好复杂!

    所以当两个坐标全为奇数时K=(奇数-奇数)+(偶数-偶数)或者K=(奇数-偶数)+(偶数-奇数)=偶数+偶数或者K=奇数+奇数;

    总而言之的言之:当两个坐标都是奇时,K=偶数;

    2.全为偶数是

    K=(奇数-奇数)+(奇数-奇数)=偶数;

    或者K=(偶数-偶数)+(偶数-偶数)=偶数;

    或者K=(奇数-偶数)+(奇数-偶数)=偶数;

    卧槽怎么写出原理这么多,快出来个人告诉我简便证法!!!

    反正总而言之!!!

    上面的都是草泥马写的!!不用看了!!

    当两个坐标奇偶性相同时,需要走的步数一定绝壁是:偶数!

    当两个坐标的奇偶性不一样的时候:

    这就简单了:其中一个一定是一奇一偶;另一个要么全是奇,要么全是偶;

    所以K=(奇数-奇数)+(奇数-偶数)或者K=(奇数-偶数)+(偶数-偶数)

    当两个坐标奇偶性不相等时,需要走的步数K都等于奇数!

    好了好了,累死我了;

    说了这么多,其实就是一个奇偶剪枝的结论:

    当两个坐标奇偶性相等时,需要走偶数步!

    当两个坐标奇偶性不相等时,需要走奇数步!

     

    翻译成C语言就是:

    if((x1+y1+x2+y2)%2==0)

    {

         两个坐标奇偶性相等;

    }

    if((x1+y1+x2+y2)%2==1)

    {

          两个坐标奇偶性不相等;

    }

    要想奇偶性相等的时候T是偶数;

    奇偶性不想等的时候T是奇数;


    只需要把上面这么一大坨的东西变成一句话(哭

    if((x1+y1+x2+y2+T)%2==0)

    AC代码:

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int dx[4]= {1,0,-1,0};
    const int dy[4]= {0,1,0,-1};
    char s[56][56];
    int n,m,t,xxx,yyy;
    int vis[105][56];
    
    int dfs(int x,int y,int cnt)
    {
        int k;
        for(int i=0; i<4; i++)
        {
            int x1=x+dx[i];
            int y1=y+dy[i];
            if(x1>=0&&x1<n&&y1>=0&&y1<m&&vis[x1][y1]==0)
            {
                if(s[x1][y1]=='.')//如果遇到"."继续往下搜
                {
                    vis[x1][y1]=1;
                    k=dfs(x1,y1,cnt+1);
                    if(k==1)
                    {
                        return 1;
                    }
                    vis[x1][y1]=0;
                }
                else if(s[x1][y1]=='D')
                {
                    if(cnt+1==t)
                    {
                        return 1;
                    }
                    else if(cnt+1>t)
                    {
                        return 0;
                    }
                }
            }
        }
        return 0;
    }
    int main()
    {
        int xx,yy;
        while(~scanf("%d%d%d",&n,&m,&t))
        {
            memset(vis,0,sizeof(vis));
            if(n==0&&m==0&&t==0)
            {
                break;
            }
            for(int i=0; i<n; i++)
            {
                scanf("%s",s[i]);
            }
            int ans=0;
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<m; j++)
                {
                    if(s[i][j]=='S')
                    {
                        xx=i;
                        yy=j;
                    }
                    else if(s[i][j]=='D')
                    {
                        xxx=i;
                        yyy=j;
                    }
                }
            }
            if(abs(xx-xxx)+abs(yy-yyy)>t||(xx+yy+xxx+yyy+t)%2==1)//普通剪枝+奇偶剪枝
            {
                printf("NO
    ");
                continue;
            }
            ans=dfs(xx,yy,0);
            if(ans)
            {
                printf("YES
    ");
            }
            else
            {
                printf("NO
    ");
            }
        }
        return 0;
    }
    View Code

     第二次做,再来一份代码:

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    int sx[4]= {1,-1,0,0};
    int sy[4]= {0,0,-1,1};
    int n,t,step[15][15],m,vis[15][15];
    char s[15][15];
    
    int dfs(int x,int y)
    {
        if(s[x][y]=='D'&&step[x][y]==t)
        {
            return 1;
        }
        if(s[x][y]=='.'||s[x][y]=='S')
        {
            for(int i=0; i<4; i++)
            {
                int kk1=x+sx[i];
                int kk2=y+sy[i];
                if(kk1>=0&&kk1<n&&kk2>=0&&kk2<m&&vis[kk1][kk2]==0)
                {
                    vis[kk1][kk2]=1;
                    step[kk1][kk2]=step[x][y]+1;
                    int kk=dfs(kk1,kk2);
                    if(kk==1)
                    {
                        return 1;
                    }
                    vis[kk1][kk2]=0;
                }
            }
        }
        return 0;
    }
    int main()
    {
        int x1,x2,k1,k2;
        while(~scanf("%d%d%d",&n,&m,&t))
        {
            if(n==0&&m==0&&t==0)
            {
                break;
            }
            for(int i=0; i<n; i++)
            {
                scanf("%s",s[i]);
                for(int j=0; j<m; j++)
                {
                    if(s[i][j]=='S')
                    {
                        x1=i;
                        x2=j;
                    }
                    else if(s[i][j]=='D')
                    {
                        k1=i;
                        k2=j;
                    }
                }
            }
            if((x1+x2+k1+k2+t)%2!=0||fabs(x1-x2)+fabs(k1-k2)>t)
            {
                printf("NO
    ");
            }
            else
            {
                memset(vis,0,sizeof(vis));
                step[x1][x2]=0;
                vis[x1][x2]=1;
                int ans=dfs(x1,x2);
                if(ans==1)
                {
                    printf("YES
    ");
                }
                else
                {
                    printf("NO
    ");
                }
            }
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    python--模块与包
    内置函数 的总结
    迭代器 生成器 列表推导式 生成器表达式的一些总结
    函数的有用信息 带参数的装饰器 多个装饰器装饰一个函数
    函数名的应用(第一对象) 闭包 装饰器
    动态参数 名称空间 作用域 作用域链 加载顺序 函数的嵌套 global nonlocal 等的用法总结
    函数的初识 函数的返回值 参数
    文件操作 常用操作方法 文件的修改
    遍历字典的集中方法 集合的作用 以及增删查的方法
    计算机硬件的小知识
  • 原文地址:https://www.cnblogs.com/qioalu/p/4905579.html
Copyright © 2020-2023  润新知