zoukankan      html  css  js  c++  java
  • codevs 1004 四子连棋

    1004 四子连棋

     时间限制: 1 s

     空间限制: 128000 KB

     题目等级 : 黄金 Gold

    题解

    题目描述 Description

    在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。

    输入描述 Input Description

    从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。

    输出描述 Output Description

    用最少的步数移动到目标棋局的步数。

    样例输入 Sample Input

    BWBO
    WBWB
    BWBW
    WBWO

    样例输出 Sample Output

    5

    思路

    这个题范围特别小,但很麻烦。

    需要考虑的东西:下次该哪个棋子走,移动哪个空白格,如何判断状态是否符合要求,如何判重

    这些问题需要一步步解决,首先我用结构体存储整个棋盘,包括棋盘里的棋子排布,下一次不该哪种棋子走(也可以认为这种局面是由哪种棋子走来而造成的)

    搜索的进行两次,一次是第一步黑子先出,另一次是第一步白子先出。

    接下来一些普通的bfs步骤

    判重用的是hash,把整个棋盘转化为由0,1,2构成的字符串,借助map完成判重

    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<cstring>
    using namespace std;
    int head,tail=1,step[10000];
    int e_[4][2]={{0,1},{1,0},{-1,0},{0,-1}},now[10][10],ans;
    struct node{
        int map[10][10];
        int f;
    };node e[10000];
    map<string,bool>hash;
    bool pd(node z){
        string s="";
        for(int i=1;i<=4;i++){
            for(int j=1;j<=4;j++){
                s+=z.map[i][j]+'1';
            }
        }
        if(hash[s]==1)return true;
        else {hash[s]=1;return false;}
    }
    bool judge(int x,int y){
        if(x<=4&&x>=1&&y<=4&&y>=1&&e[head].map[x][y]!=0&&e[head].map[x][y]!=e[head].f)
        return true;
        return false;
    }
    void copy(){
        for(int i=1;i<=4;i++)
            for(int j=1;j<=4;j++)
                e[tail].map[i][j]=e[head].map[i][j];
    }
    bool equ(int a1,int a2,int a3,int a4){if(a1!=a2||a2!=a3||a3!=a4||a4!=a1)return 0;return 1;}
    bool check(int w)
    {
        for(int i=1;i<=4;i++)
        {
            if(equ(e[w].map[i][1],e[w].map[i][2],e[w].map[i][3],e[w].map[i][4]))return 1;
            if(equ(e[w].map[1][i],e[w].map[2][i],e[w].map[3][i],e[w].map[4][i]))return 1;
        }
        if(equ(e[w].map[1][1],e[w].map[2][2],e[w].map[3][3],e[w].map[4][4]))return 1;
        if(equ(e[w].map[1][4],e[w].map[2][3],e[w].map[3][2],e[w].map[4][1]))return 1;
        return 0;
    }
    void bfs(){
        while(head<tail){
            head++;
            for(int i=1;i<=4;i++){
                for(int j=1;j<=4;j++){
                    if(e[head].map[i][j]==0){
                        for(int k=0;k<4;k++){
                            int xx=e_[k][0]+i,yy=e_[k][1]+j;
                            if(judge(xx,yy)){
                                tail++;
                                copy();
                                e[tail].map[xx][yy]=0;
                                if(e[head].f==1){
                                    e[tail].map[i][j]=-1;
                                    e[tail].f=-1;
                                }
                                else{
                                    e[tail].map[i][j]=1;
                                    e[tail].f=1;
                                }step[tail]=step[head]+1;
                                if(check(tail)){ans=min(ans,step[tail]);return;}
                                if(pd(e[tail]))tail--;
                            }
                        }
                    }
                }
            }
        }
    }
    char ch[10];
    int main(){
        
        ans=0x7fffffff;
        for(int i=1;i<=4;i++){
            cin>>ch;
            for(int j=1;j<=4;j++){
                if(ch[j-1]=='W')now[i][j]=1;
                if(ch[j-1]=='B')now[i][j]=-1;
                if(ch[j-1]=='O')now[i][j]=0;
            }
        }
        for(int i=1;i<=4;i++)
            for(int j=1;j<=4;j++)
                e[1].map[i][j]=now[i][j];
        e[1].f=1;
        bfs();
        head=0;tail=1;
        memset(e,0,sizeof(e));
        memset(step,0,sizeof(step));
        hash.clear();
        for(int i=1;i<=4;i++)
            for(int j=1;j<=4;j++)
                e[1].map[i][j]=now[i][j];
        e[1].f=-1;
        bfs();
        cout<<ans;
    }
  • 相关阅读:
    Minimum Sum of Array(map迭代器)
    stl库中的map (反向迭代器)以及例题
    stl库中反转的函数
    如何使用java中的对象
    java中的成员变量和局部变量
    java中的构造方法
    static使用之静态变量
    什么是类和对象
    如何定义java中的类
    css让图片作为按钮的背景并且大小合适
  • 原文地址:https://www.cnblogs.com/thmyl/p/7359297.html
Copyright © 2011-2022 走看看