hdu 1175 连连看

基础搜索

中文题意不解释,这题没看sample直接看完题目就打,发现不对,才看到数据可能各种无聊的坑

1.可能出现相同位置的点,直接判NO

2.两个点中,可能一个点是空白点,直接判NO

3.两个点的值不同,直接判NO

剩下的情况才是值得去搜索的,即两点值相同且都不是空白

同BFS去搜

定义状态,包括信息有

1.x,y即该点在盘中的坐标

2.c,从起点走到这里,转弯次数,为0,1,2。  3或以上的已经不行了,直接抛弃掉

3.n,方向,从什么方向来到这个点,有0,1,2,3表示上,左,右,下,这样排序方便计算

 

然后每次从当前点往4个方向搜索,并且开一个标记数组来标记哪些状态在队列中,inq[x][y][c][n],耗时6500ms

将标记数组压缩为三维,inq[x][y][n],耗时3700ms,还是比较糟糕

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 1010
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))

//对应上左右下四个方向的变化,这样排列4个方向是为了方便计算
const int dx[4] = {-1,0,0,1};
const int dy[4] = {0,-1,1,0};

int row,col,query;
int map[N][N];
bool inq[N][N][4];
struct state{
    int x,y; //点的坐标,可以写成编号,但是坐标更好
    int c; //转弯次数
    int n;  //从哪个方向来的
};
typedef struct state state;

int bfs(int x1 ,int y1 ,int x2 ,int y2)
{
    queue<state>q;
    state temp;
    while(!q.empty()) q.pop();
    memset(inq,false,sizeof(inq));
    temp.x = x1;  temp.y = y1;
    temp.c = 0;   temp.n = -1; //初始化状态没有方向用-1表示
    q.push(temp);
    while(!q.empty())
    {
        int x,y,c,n;
        temp = q.front();
        q.pop();

        x = temp.x;  y = temp.y;
        c = temp.c;  n = temp.n;
        inq[x][y][n] = false;

        for(int k=0; k<4; k++) //扫描4个方向
        {
            int cc,nn;
            int xx = x + dx[k];
            int yy = y + dy[k];
            
            if(n == k) continue;//走回原来的格子 
            if(n == -1){//起始状态
                cc = 0; //转弯数不用增加
                nn = 3 - k; 
            }
            else if(n + k == 3){//说明方向没有改变
                cc = c; //那么转弯次数不变
                nn = n;  //方向当然不变
            }
            else{//既不是起始状态也不是沿相同方向
                cc = c + 1;
                nn = 3 - k;
            }

            if( xx < 1 || xx > row || yy < 1 || yy > col) continue; //越过了迷宫,放弃
            if( cc > 2) continue;//转弯次数大于2,放弃
            if(xx == x2 && yy == y2) return 1;//找到了目标
            if(map[xx][yy]) continue; //不是空白格子
            if(inq[xx][yy][nn]) continue;
            temp.x = xx;  temp.y = yy;
            temp.c = cc;  temp.n = nn;
            q.push(temp);
            inq[xx][yy][nn] = true;
        }
    }
    return 0;
}

int main()
{
    while(scanf("%d%d",&row,&col)!=EOF)
    {
        if(!row && !col) break;
        for(int i=1; i<=row; i++)
            for(int j=1; j<=col; j++)
                scanf("%d",&map[i][j]);

        int x1,y1,x2,y2;
        scanf("%d",&query);
        for(int i=0; i<query; i++)
        {
            int ok;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            if(x1 == x2 && y1 == y2)
                ok = 0;
            else if(map[x1][y1] != map[x2][y2] || !map[x1][y1] || !map[x2][y2])
                ok = 0;
            else
                ok = bfs(x1,y1,x2,y2);
        
            if(ok) printf("YES\n");
            else   printf("NO\n");
        }
    }
    return 0;
}

 

 

posted @ 2013-05-05 10:35  Titanium  阅读(273)  评论(0)    收藏  举报