hdoj 1175-连连看

本文提供HDOJ 1175连连看问题的标准解法,采用C++实现BFS(宽度优先搜索)算法,并结合搜索记忆化技术来优化搜索过程。该算法通过限制新结点的转弯次数不超过当前方向的最大转弯次数来减少冗余搜索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
hdoj 1175-连连看
written by lky

501994    2008-03-18 14:53:30    Accepted    1175    781MS    8868K    2269 B    C++    lky

标准bfs+搜索记忆化,新结点的turn数小于在该方向上的turn数时才入队列
*/
#include <iostream>
#include <queue>
using namespace std;
#define  MAX 999999
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int MAP[1001][1001];
int val[1001][1001][5];
int m, n, turn;
typedef struct
{
    int x, y;
    int direction;
    int nturn;
}Node;
int main()
{
    int nn;
    int i, j, k;
    Node s, t, tt;
    int sx, sy, ex, ey;
    queue<Node> q;
    while (cin >> m >> n)
    {
        if (m == 0 && n == 0)
            break;
        turn = 2;
        for (i = 0; i < m; i++)
            for (j = 0; j < n; j++)
                cin >> MAP[i][j];
        cin >> nn;
        while (nn--)
        {
            int temp;
            for (i = 0; i < m; i++)
                for(j = 0; j < n; j++)
                    for(k = 1; k <= 4; k++)
                        val[i][j][k] = MAX;
            cin >> sx >> sy >> ex >> ey;
            sy--, sx--, ey--, ex--;
            //判断同一个点
            if (sx == ex && sy == ey)
            {
                cout << "YES" << endl;
                continue;
            }
            //判断不是同一种类
            if (MAP[sx][sy] != MAP[ex][ey])
            {
                cout << "NO" << endl;
                continue;
            }
            //判断有至少有一个没有棋子
            if (MAP[sx][sy] == 0 || MAP[ex][ey] == 0)
            {
                cout << "NO" << endl;
                continue;
            }

            temp = MAP[ex][ey];
            MAP[ex][ey] = 0;
            bool flag = false;
            s.x = sx, s.y = sy, s.nturn = 0, s.direction = 0;
            for (i = 1; i <= 4; i++)
                val[s.x][s.y][i] = 0;
            q.push(s);
            while (!q.empty())
            {
                t = q.front();
                q.pop();
               
                if (t.x == ex && t.y == ey && t.nturn <= turn)
                {
                    flag = true;
                    break;
                }
               
                for (i = 0; i < 4; i++)
                {
                    tt.x = t.x + dir[i][0];
                    tt.y = t.y + dir[i][1];
                    tt.direction = t.direction;
                    tt.nturn = t.nturn;
                    if (MAP[tt.x][tt.y] == 0 && tt.x>=0&&tt.x<m && tt.y>=0&&tt.y<n)
                    {
                        if (tt.direction == 0) //第一次
                        {
                            tt.direction = i + 1;
                        }
                        else if (tt.direction != i + 1) // 转弯
                        {
                            tt.direction = i + 1;
                            tt.nturn++;
                        }
                        if (tt.nturn < val[tt.x][tt.y][tt.direction] && tt.nturn <= turn)
                        {
                            val[tt.x][tt.y][tt.direction] = tt.nturn;
                            q.push(tt);
                        }
                    }
                }
            }
            while (!q.empty())
            {
                q.pop();
            }
            if (flag)
            {
                cout << "YES" << endl;
            }
            else
                cout << "NO" << endl;
            MAP[ex][ey] = temp;
        }
    }
    return 0;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值