码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1010

时间:2015-10-23 21:21:47      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:

题意:一只狗(柴犬,看到一块骨头,迷失在了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\n");
            continue;
        }
        ans=dfs(xx,yy,0);
        if(ans)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }
    return 0;
}
View Code

 

HDU 1010

标签:

原文地址:http://www.cnblogs.com/qioalu/p/4905579.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!