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;

}

 

 

你可能感兴趣的:(HDU)