HDU 1175 连连看

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1175

 

广搜  BFS

主要问题是怎样记录拐弯次数,用方向标记,比较上一次路线方向和当前路线方向,如不同拐弯次数+1,相同拐弯次数不变。

这里用到一个小技巧,初始化 visit 很大,当前拐弯次数小于 visit 时,才将当前拐弯次数赋值给 visit ,然后push。

 

代码如下:思路很清晰

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;

/*
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
*/

int maps[1001][1001],visit[1001][1001];
int n,m;
int xx1,x2,yy1,y2;
int t[4][2]={-1,0,1,0,0,-1,0,1};

struct xh
{
    int x,y;//坐标
    int step;//拐弯次数
    int distant;//上一次走的方向,判断拐弯
}w,ww;

bool panduan(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m;
}

void bfs()
{
    queue<xh>q;
    q.push(w);
    while(!q.empty())
    {
        ww=q.front();
        q.pop();
        if(ww.step>2)
        {
            continue;
        }
        for(int i=0;i<4;i++)
        {
            w=ww;
            w.x+=t[i][0];
            w.y+=t[i][1];
            w.distant=i;
            if(panduan(w.x,w.y)&&(maps[w.x][w.y]==0||w.x==x2&&w.y==y2))
            {
                if(ww.distant!=520&&ww.distant!=w.distant)
                    w.step++;
                if(w.step>2)
                    continue;
                if(visit[w.x][w.y]>=w.step)//这个地方一定是大于等于,因为可能回搜
                {
                    visit[w.x][w.y]=w.step;
                    q.push(w);
                }
                if(w.x==x2&&w.y==y2)
                {
                    printf("YES\n");
                    return ;
                }

            }
        }
    }
    printf("NO\n");
    return ;
}

int main()
{
    int i,j,k;
    while(cin>>n>>m&&n+m)
    {
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                scanf("%d",&maps[i][j]);
        scanf("%d",&k);
        while(k--)
        {
            scanf("%d%d%d%d",&xx1,&yy1,&x2,&y2);
            if(maps[xx1][yy1]!=maps[x2][y2]||maps[xx1][yy1]==0)//不是同一个数或为0,直接输出NO
            {
                printf("NO\n");
                continue;
            }
            memset(visit,1,sizeof(visit));//将visit初始化大一些
            w.x=xx1;
            w.y=yy1;
            w.step=0;
            w.distant=520;//初始化方向
            visit[w.x][w.y]=0;
            bfs();
        }
    }
    return 520;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值