• 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;
    }
  • 相关阅读:
    C++对象数组与对象指针
    C++析构函数
    centos7下安装mysql
    Java杂知识汇总(自己积累的)
    利用json模块解析dict报错找不到attribute 'dumps'[python2.7]
    Linux删除除了今天以外的文件
    docker简单介绍(资料收集总结)
    python不可以打印.doc文件
    python安装模块的时候报错error: command 'gcc' failed with exit status 1
    yum和head一起用,报错“由于管道被破坏而退出”
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3060673.html
Copyright © 2020-2023  润新知