hdoj 1175 (bfs)

 

题意:

判断两点之间是否可以通过至多有两次转变方向以达到相连,就是平时玩的连连看游戏,但是不能从外面绕过去。

 

思路:bfs,给每个加入的队列的点添加转变方向次数turn和点当前要走的方向dir属性,起点可以走四个方向。

参照代码来源

我的代码,参照写得,加深练习和理解:

#include <iostream>
#include <cstring>
#include <queue>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int M = 1005;
int map[M][M];
int has[M][M];
struct node
{
    int x,y;
    int turn;
    int dir;
};
int dire[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
queue <node> q;
int n,m;
int sx,sy,ex,ey;
struct node st;
bool flag;
inline bool in(const node &p)
{
    if ((p.x<0 || p.y<0 || p.x>=n || p.y>=m))
        return false;
    return true;
}
void bfs()
{
    node now,t;
    while (!q.empty())
    {
        now = q.front();
        q.pop();
        //cout << now.x << " " << now.y << " " << now.turn << " " << now.dir <<endl;
        if (now.x == ex && now.y == ey && now.turn<=2)  //满足条件退出
        {
            flag = true;
            return;
        }
        for (int i = 0; i < 4; i++)
        {
            if((now.dir+2)%4 == i) continue;          
            t.x=now.x+dire[i][0],t.y=now.y+dire[i][1];
            if(i == now.dir)          //now的点和下一个走的点的方向相同
                 t.turn=now.turn,t.dir=now.dir;
            else
                 t.turn=now.turn+1,t.dir=i;
            //if ((t.x>=0 && t.x < n && t.y>=0 && t.y<m) && (map[t.x][t.y] == 0|| (t.x == ex&&t.y == ey))&& (has[t.x][t.y]>=t.turn)) //如果不用in()函数的话我之前是这么写的
            if (in(t) && (map[t.x][t.y] == 0|| (t.x == ex && t.y == ey))&& (has[t.x][t.y]>=t.turn) && t.turn <= 2) // 加入队列条件
            {
                has[t.x][t.y] = t.turn;
                q.push(t);
            }
        }
    }
}

int main()
{
    while (cin >> n >> m && n && m)
    {
        for (int i = 0;i < n;i++)
        {
            for (int j = 0;j < m;j++)
                cin >> map[i][j];
        }
        int tt;
        cin >> tt;
        for (int i = 0;i < tt;i++)
        {
            cin >> sx >> sy >> ex >> ey;
            sx--,sy--,ex--,ey--;
            //printf("%d %d %d %d\n",sx,sy,ex,ey);
            if ((sx == ex && sy == ey)|| map[sx][sy] == 0 || map[ex][ey] == 0 ||map[sx][sy] != map[ex][ey]) //判断输入的两点是否合法:是否相等,是否为0...
            {
                 puts("NO");
                 continue;
            }
            for (int i = 0;i < n;i++)
                for (int j = 0;j < m;j++)
                    has[i][j] = 111;
            while(!q.empty())
                q.pop();
            for (int i = 0;i < 4;i++)
            {
                st.x = sx,st.y = sy,st.turn = 0,st.dir = i;    //起点的四个方向都要加入队列
                q.push(st);
            }
            has[sx][sy] = 0;
            flag = false;
            bfs();
            if(flag)
                cout << "YES\n";
            else cout << "NO\n";
        }
    }
    return 0;
}

 

posted @ 2015-08-20 19:05  ediszhao  阅读(131)  评论(0编辑  收藏  举报