第一个bfs题目 hdu1175连连看

本文介绍了一种使用广搜算法解决特定图中消除特定点问题的方法,通过构建图、判断点合法性、实现广搜算法并判断是否可以消除目标点,最后输出是否可行的结论。

 

#include <iostream>

#include <string.h>

#include <queue>

using namespace std;

 

#define MAXN 1005

 

//用于保存点信息的结构

typedef struct _node

{

int x, y; //坐标信息

unsigned short change; //转弯次数信息

int dic; //点的方向信息

}node;

int cmap[MAXN][MAXN]; //保存图信息

int vistied[MAXN][MAXN]; //记录点是否已访问过

int flag; //标识点是否可消除

int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; //用于保存4个方向的数组

int m, n;

int xs, ys, xe, ye;

int legal(int x, int y); //判断点是否合法

void bfs(int sx, int sy); //广搜算法

 

int main(void)

{

    int i, j, q;

 

    while (scanf("%d %d", &m, &n) && (m + n))

    {

        memset(cmap, -1, sizeof(cmap));

//构图

        for (i=1; i<=m; i++)

        {

            for (j=1; j<=n; j++)

            {

                scanf("%d", &cmap[i][j]);

            }

        }

 

        scanf("%d", &q);

 

        while (q--)

        {

            flag = 0;

            memset(vistied, 0, sizeof(vistied));

            scanf("%d%d%d%d", &xs, &ys, &xe, &ye);

//如果所选点值或起始点和结尾点为0则表示无法消除

            if (cmap[xs][ys] != cmap[xe][ye] || cmap[xs][ys] == 0 || cmap[xe][ye] == 0)

            {

                printf("NO/n");

            }

            else

            {

                bfs(xs, ys);

 

                if (flag)

                {

                    printf("YES/n");

                }

                else

                {

                    printf("NO/n");

                }

            }

        }

 

    }

    return 0;

}

 

int legal(int x, int y)

{

    if (x<0 || x>m || y<0 || y>n)

    {

        return 0;

    }

 

    return 1;

}

 

//广搜算法

void bfs(int sx, int sy)

{

queue<node> que; //用于保存合法点的队列

node p, t;

    int i;

p.x = sx; //初始化节点

p.y = sy;

p.change = 0;

p.dic = -1;

t.dic = -1;

t.change = 0;

    vistied[p.x][p.y] = 1;

que.push(p); //将起始节点入队

 

while (!que.empty())

{

p = que.front();

que.pop();

//出队节点如果和结束节点位置相同则表示可以删除,计算结束

if (p.x == xe && p.y == ye)

{

flag = 1;

break;

}

for (i=0; i<4; i++)

{

t.x = p.x + dir[i][0];

t.y = p.y + dir[i][1];

//用于改变节点转弯次数信息和方向信息

if (p.dic != -1)

{

if (p.dic != i)

{

t.change = p.change + 1;

}

else

{

t.change = p.change;

}

}

else

{

t.change = 0;

}

 

t.dic = i;

//转弯次数小于等于2且点合法且未被访问过,点值为0或者该点是结束点则符合条件入队

if (t.change <=2 && legal(t.x, t.y) && !vistied[t.x][t.y] 

&& (cmap[t.x][t.y] == 0 || (t.x == xe && t.y == ye)))

{

que.push(t);

vistied[t.x][t.y] = 1;

}

}

}

 

}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值