hud 1175 连连看

#include <iostream>
#include <cstdio>
#include <cstring>


using namespace std;
/*
本题所得; 深搜的难点是剪枝, 对于搜索,我们一定要尽量控制进入递归搜索的次数, 对于题目给出的数据
       尽量找到不合题意的情况, 将其剪去; 在递归中也是一样,想尽一切办法剪枝,
*/

int mmap[1005][1005];
int vist[1005][1005];

int n, m;
int T;
int flag, t, pos;

int dir[][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1} };

int judge(int x, int y) {

    if(x >= 1 && x <= n && y >= 1 && y <= m && vist[x][y] == 0)
        return 1;
    return 0;

}
/*  本代码 转弯从1 开始, 顾可以转三次;
void dfs(int x, int y, int a, int b) {

   if(t)
    return;
   if(x == a && y == b) { //找到目标,且步数少于3;

        if(pos <= 3)
            t = 1;
        return ;
   }
   if(pos > 3)  //步数大于3 , 剪枝;
    return ;
   if(mmap[x][y] != 0 && flag != 0) {//当前格不是通路, 但要除去开始搜索处,flag = 0 的情况;

        return;
   }
   if(pos == 3 && x - a != 0 && y - b != 0) // 当前转弯次数为3, x - a != 0 && y - b != 0 则要到达目标一定还要转弯;
    return;                                  //顾剪枝;
   vist[x][y] = 1;  //当前不标记为 走过;
   for(int i = 0; i < 4; i++) {  //用i 从1 到4 表示四个方向;

        int nextx = x + dir[i][0];
        int nexty = y + dir[i][1];
        int temp = flag; //保留当前,方向;
        if(!vist[nextx][nexty] && nextx >= 1 && nexty  >= 1 && nextx <= n && nexty <= m)
        {

            if(flag != i + 1) //判断是否与当前方向相同;
            {
                pos++;         //表示改变方向数加一;
                flag = i + 1;  //更新当前方向;
                dfs(nextx, nexty, a, b);
                 pos--;         //还原当前方向改变数;
            }
            else
            {
                flag = i + 1;
                dfs(nextx, nexty, a, b);
            }
           flag = temp; //还原当前方向;
        }

   }
   vist[x][y] = 0;//当前点还原为未走过;


}

int main()
{
    int sx, sy, ex, ey;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        if(m == 0 && m == 0)
            break;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                scanf("%d", &mmap[i][j]);
                vist[i][j] =0;
            }
        }

        scanf("%d", &T);
        while(T--)
        {
             flag = 0;
            t = 0;
             pos = 0;
            scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
            if(mmap[sx][sy] == mmap[ex][ey] && mmap[sx][sy] != 0)
            {
               dfs(sx, sy, ex, ey);
            if(t)
                printf("YES\n");
            else
                printf("NO\n");
            }
            else
                printf("NO\n");

        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值