0
点赞
收藏
分享

微信扫一扫

计蒜客 实现奇偶性剪枝(简洁明了)

生态人 2022-04-06 阅读 42

本人大一,才疏学浅,多多指教,步入正题。

我直接将个人理解与代码相结合。

上代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int t;
bool f;                           //成功与否的标记 
char mp[110][110];                
bool v[110][110];                 //映射  
int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};//上下左右四方向不多bb 
void dfs(int x,int y,int s)
{
    if(f)
    {
        return ;
    }
    if(s>t)
    {
        //剪枝 
        return ;
    }
    if(s==t)
    {
        //剪枝,可以减去s==t都是非出口的情况 
        if(mp[x][y]=='D')
            f=true;
        return ;
    }
    v[x][y]=true;
    for(int i=0; i<4; i++)
    {
        int tx=x+dir[i][0];
        int ty=y+dir[i][1];
        if(0<=tx&&tx<n&&0<=ty&&ty<m&&mp[tx][ty]!='X'&&!v[tx][ty])
        {
            v[tx][ty]=true;//标记 
            dfs(tx,ty,s+1);
            v[tx][ty]=false;//为回溯做准备 
        }
    }
    v[x][y]=false;
}
int main()
{
    cin>>n>>m>>t;
    for(int i=0; i<n; i++)
    {
        scanf("%s",mp[i]);
    }
    int qx,qy;
    int zx,zy;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            if(mp[i][j]=='S')
            {
                qx=i;
                qy=j;
            }
            else if(mp[i][j]=='D')
            {
                zx=i;
                zy=j;
            }
            /* 第一部分,标记起点的x,y坐标 :qx,qy */ 
            /* 第二部分,标记终点的x,y坐标 :zx,zy */ 
        }
    }
    if((qx+qy+zx+zy+t)%2!=0)
    /*剪枝: 重点如果起点xy和与终点xy和同为奇/偶数,则步数均为奇/偶数*/ 
    /*       起点xy和与终点xy和相加肯定是偶数   通俗来讲也就是说t是偶数才有yes的可能性*/
    /*       相反一个点是奇数,另一个是偶数,那两点之和肯定是奇数,对应t也是奇数*/
    /*无论哪种情况三数之和肯定是偶数,才有yes的可能性*/ 
    {
        printf("NO\n");
    }
    else
    {
        dfs(qx,qy,0); 
        if(f)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }
    return 0;
}

你的收藏点赞评论是激励我的动力!!!

有不足指出必感激!!!

举报

相关推荐

0 条评论