zoukankan      html  css  js  c++  java
  • hdu 1401(单广各种卡的搜索题||双广秒速)

    Solitaire

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 4122    Accepted Submission(s): 1245


    Problem Description
    Solitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered from 1 to 8, from the top to the bottom and from left to right respectively.

    There are four identical pieces on the board. In one move it is allowed to:

    > move a piece to an empty neighboring field (up, down, left or right),

    > jump over one neighboring piece to an empty field (up, down, left or right).



    There are 4 moves allowed for each piece in the configuration shown above. As an example let's consider a piece placed in the row 4, column 4. It can be moved one row up, two rows down, one column left or two columns right.

    Write a program that:

    > reads two chessboard configurations from the standard input,

    > verifies whether the second one is reachable from the first one in at most 8 moves,

    > writes the result to the standard output.
     
    Input
    Each of two input lines contains 8 integers a1, a2, ..., a8 separated by single spaces and describes one configuration of pieces on the chessboard. Integers a2j-1 and a2j (1 <= j <= 4) describe the position of one piece - the row number and the column number respectively. Process to the end of file.
     
    Output
    The output should contain one word for each test case - YES if a configuration described in the second input line is reachable from the configuration described in the first input line in at most 8 moves, or one word NO otherwise.
     
    Sample Input
    4 4 4 5 5 4 6 5 2 4 3 3 3 6 4 6
     
    Sample Output
    YES
     
    题意:给定4个点的初始状态,点每次移动可以有两种方式。一种是如果相邻点是空的,移动到相邻点,如果相邻点非空,并且相邻点同一个方向没有点,则可以跳过去到下一个点,问8步以内能否移动到目标状态??
    题解:4个点可以想到用8维数组保存状态,,但是一定要压缩压缩再压缩,强剪枝。。自己代码剪枝没通过,参考的大神的,,不过双向BFS好像快些。。而且只能用G++交才能AC。
    #include<stdio.h>
    #include<queue>
    #include<iostream>
    #include <string.h>
    #include <algorithm>
    #include <map>
    using namespace std;
    typedef long long LL;
    struct Node{
        int x[4],y[4];
        int step;
    }s,t;
    int graph[10][10];
    bool vis[8][8][8][8][8][8][8][8];
    bool equals(Node a){ ///这个地方开始想错了,以为是每一个点的状态对应下一行每一行的状态,结果是只要能到达目标
        ///状态就OK,比如说是起始地第二个点到达目标的第一个点
        for(int i=0;i<4;i++){
            if(!graph[a.x[i]][a.y[i]]) return false;
        }
        return true;
    }
    bool check(Node a){
        for(int i=0;i<4;i++){
            if(a.x[i]<0||a.x[i]>=8||a.y[i]<0||a.y[i]>=8) return false;
        }
        if(vis[a.x[0]][a.y[0]][a.x[1]][a.y[1]][a.x[2]][a.y[2]][a.x[3]][a.y[3]]) return false;
        return true;
    }
    bool cango(Node next,int k){
        for(int i=0;i<4;i++){
            if(i!=k&&next.x[i]==next.x[k]&&next.y[i]==next.y[k]) return false;
        }
        return true;
    }
    int dir[][2] = {{1,0},{-1,0},{0,1},{0,-1}};
    
    bool bfs(){
        queue<Node> q;
        q.push(s);
        s.step = 0;
        while(!q.empty()){
            Node now = q.front();
            q.pop();
            if(now.step>8){
                return false;
            }
            if(equals(now)){
                return true;
            }
            for(int i=0;i<4;i++){
                for(int j=0;j<4;j++){
                    Node next = now;
                    next.x[i] = now.x[i]+dir[j][0];
                    next.y[i] = now.y[i]+dir[j][1];
                    next.step = now.step+1;
                    if(next.step>8) continue; ///大神的剪枝是>=8
                    if(!check(next)) continue;
                    if(cango(next,i)){
                        if(equals(next)) return true;
                        vis[next.x[0]][next.y[0]][next.x[1]][next.y[1]][next.x[2]][next.y[2]][next.x[3]][next.y[3]] = true;
                        q.push(next);
                    }
                    else{
                        next.x[i] = now.x[i]+2*dir[j][0];
                        next.y[i] = now.y[i]+2*dir[j][1];
                        if(!check(next)) continue;
                        if(cango(next,i)){
                            if(equals(next)) return true;
                            vis[next.x[0]][next.y[0]][next.x[1]][next.y[1]][next.x[2]][next.y[2]][next.x[3]][next.y[3]] = true;
                            q.push(next);
                        }
                    }
                }
            }
        }
        return false;
    }
    int main()
    {
        while(scanf("%d%d",&s.x[0],&s.y[0])!=EOF){
            memset(graph,0,sizeof(graph));
            s.x[0]-=1,s.y[0]-=1;
            for(int i=1;i<4;i++){
                scanf("%d%d",&s.x[i],&s.y[i]);
                s.x[i]--;
                s.y[i]--;
            }
            for(int i=0;i<4;i++){
                scanf("%d%d",&t.x[i],&t.y[i]);
                t.x[i]--;
                t.y[i]--;
                graph[t.x[i]][t.y[i]] = 1;
            }
            memset(vis,false,sizeof(vis));
            vis[s.x[0]][s.y[0]][s.x[1]][s.y[1]][s.x[2]][s.y[2]][s.x[3]][s.y[3]] = true;
            bool flag = bfs();
            if(flag) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }

     双广的话非常快,主要是怎么处理初始状态和目标状态,因为有可能第1个最后跳到二状态去了,这里的解决办法是排个序之后就解决了。

    #include<stdio.h>
    #include<queue>
    #include<iostream>
    #include <string.h>
    #include <algorithm>
    #include <map>
    using namespace std;
    typedef long long LL;
    struct Point{
        int x,y;
    };
    struct Node{
        Point p[4];
        int step;
    }s,t;
    char vis[8][8][8][8][8][8][8][8];
    int graph[10][10];
    int cmp(Point a,Point b){
        if(a.x==b.x) return a.y<b.y;
        return a.x<b.x;
    }
    void make_vis(Node s,char c){
        vis[s.p[0].x][s.p[0].y][s.p[1].x][s.p[1].y][s.p[2].x][s.p[2].y][s.p[3].x][s.p[3].y] = c;
    }
    char checkvis(Node s){
        return vis[s.p[0].x][s.p[0].y][s.p[1].x][s.p[1].y][s.p[2].x][s.p[2].y][s.p[3].x][s.p[3].y];
    }
    void make_graph(Node s){
        memset(graph,0,sizeof(graph));
        for(int i=0;i<4;i++){
            graph[s.p[i].x][s.p[i].y] = 1;
        }
    }
    bool check(Node s){
        for(int i=0;i<4;i++){
            if(s.p[i].x<0||s.p[i].x>=8) return false;
            if(s.p[i].y<0||s.p[i].y>=8) return false;
        }
        return true;
    }
    int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    bool bfs(){
        memset(vis,0,sizeof(vis));
        make_vis(s,'1');
        make_vis(t,'2');
        queue<Node> q1,q2;
        q1.push(s);
        q2.push(t);
        while(!q1.empty()||!q2.empty()){
            if(!q1.empty()){
                Node now = q1.front();
                q1.pop();
                if(now.step>=4) continue;
                make_graph(now);
                for(int i=0;i<4;i++){
                    for(int j=0;j<4;j++){
                        Node next = now;
                        next.p[i].x += dir[j][0];
                        next.p[i].y += dir[j][1];
                        next.step++;
                        if(!check(next)) continue;
                        if(graph[next.p[i].x][next.p[i].y]){
                            next.p[i].x += dir[j][0];
                            next.p[i].y += dir[j][1];
                            if(!check(next)||graph[next.p[i].x][next.p[i].y]) continue;
                        }
                        sort(next.p,next.p+4,cmp);
                        if(checkvis(next)=='1') continue;
                        else if(checkvis(next)=='2') return true;
                        make_vis(next,'1');
                        q1.push(next);
                    }
                }
            }
            if(!q2.empty()){
                Node now = q2.front();
                q2.pop();
                if(now.step>=4) continue;
                make_graph(now);
                for(int i=0;i<4;i++){
                    for(int j=0;j<4;j++){
                        Node next = now;
                        next.p[i].x += dir[j][0];
                        next.p[i].y += dir[j][1];
                        next.step++;
                        if(!check(next)) continue;
                        if(graph[next.p[i].x][next.p[i].y]){
                            next.p[i].x += dir[j][0];
                            next.p[i].y += dir[j][1];
                            if(!check(next)||graph[next.p[i].x][next.p[i].y]) continue;
                        }
                        sort(next.p,next.p+4,cmp);
                        if(checkvis(next)=='2') continue;
                        else if(checkvis(next)=='1') return true;
                        make_vis(next,'2');
                        q2.push(next);
                    }
                }
            }
        }
        return false;
    }
    int main()
    {
        while(scanf("%d%d",&s.p[0].x,&s.p[0].y)!=EOF){
            memset(graph,0,sizeof(graph));
            s.p[0].x-=1,s.p[0].y-=1;
            for(int i=1;i<4;i++){
                scanf("%d%d",&s.p[i].x,&s.p[i].y);
                s.p[i].x--;
                s.p[i].y--;
            }
            for(int i=0;i<4;i++){
                scanf("%d%d",&t.p[i].x,&t.p[i].y);
                t.p[i].x--;
                t.p[i].y--;
            }
            s.step = t.step = 0;
            sort(s.p,s.p+4,cmp);
            sort(t.p,t.p+4,cmp);
            bool flag = bfs();
            if(flag) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    5月18日InterlliJ IDea快捷键
    5月17日-集合构架Collection学习
    十一java作业1
    十一java作业2
    第一周,java模拟ATMdos界面程序源代码及感想
    8.27-9.2第八周
    8.20-8.26第七周
    8.13-8.19第六周
    8.6-8.12第五周
    7.30-8.5第四周
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5592638.html
Copyright © 2011-2022 走看看