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

    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

     
    #include<iostream>
    #include<cstdio>
    #include<cstdio>
    
    using namespace std;
    int map[5][5],ans,flag;
    int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
    inline void dfs(int ch, int deep);
    
    inline void swap(int &a,int &b)
    {
        int t = a;
        a = b;
        b = t;
    }
    
    bool check()//判断是否符合条件 
    {
        for (int k=1;k<=4;k++)
        {
            if (map[k][1]==map[k][2]&&map[k][2]==map[k][3]&&map[k][3]==map[k][4])return 1;
            if (map[1][k]==map[2][k]&&map[2][k]==map[3][k]&&map[3][k]==map[4][k])return 1;
        }
        if (map[1][1]==map[2][2]&&map[2][2]==map[3][3]&&map[3][3]==map[4][4])return 1;
        if (map[1][4]==map[2][3]&&map[2][3]==map[3][2]&&map[3][2]==map[4][1])return 1;
        return 0;
    }
    
    void move(int ch,int deep,int x,int y) //ch表示下一个颜色 
    {
        for(int i=1;i<=4;i++)
        {
            int xx=x+dx[i],yy=y+dy[i];
            if(map[xx][yy]==ch&&xx>0&&xx<5&&yy>0&&yy<5)
            {
                swap(map[x][y],map[xx][yy]);
                dfs(ch,deep+1);
                swap(map[x][y],map[xx][yy]);
            }
        }
    }
    
    void dfs(int ch,int deep)
    {
        int next=!ch;
        if(flag) return;
        if(ans==deep)
        {
            if(check()) flag=1;
            return;
        }
        for(int i=1;i<=4;i++)
          for(int j=1;j<=4;j++)
            if(map[i][j]==-1) move(next,deep,i,j);
    }
    
    int main()
    {
        for(int i = 1; i <= 4; i++)
               for(int j = 1; j <= 4; j++)
               {
                   char a;
                   cin>>a;
                   if(a == 'B') map[i][j] = 1;
                   if(a == 'O') map[i][j] = -1;
               }
        for(ans = 1; flag == 0; ans++)
        {
            dfs(0, 0);
            if(flag) break;
            dfs(1, 0);
            if(flag) break;
        }
        printf("%d
    ",ans);
    }
    dfs
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #define maxn 5001
    
    using namespace std;
    struct node
    {
        int map[5][5];
        int f;//表示这一步走的棋子是黑还是白 
    };node e[5000];
    int mm[5][5],tep[maxn],head=0,tail=1,ans=maxn,flag;
    int dx[5]={0,0,0,1,-1};
    int dy[5]={0,1,-1,0,0};
    map<string,bool> hash;
    
    bool equ(int a1,int a2,int a3,int a4){if(a1!=a2||a2!=a3||a3!=a4||a4!=a1)return 0;return 1;}
    bool judge(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 copy()
    {
        for(int k=1;k<=4;k++)
          for(int l=1;l<=4;l++)
            e[tail].map[k][l]=e[head].map[k][l];
    }
    
    bool check(node x)//hash判重 
    {
        string s="";
        for(int i=1;i<=4;i++)
            for(int j=1;j<=4;j++)
                s+=x.map[i][j]+'1';
        if(hash[s])return true;
        hash[s]=1;return false;
    }
    
    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 cnt=1;cnt<=4;cnt++)
                      {
                          int x=i+dx[cnt],y=j+dy[cnt];
                          if(x>0&&x<5&&y>0&&y<5&&e[head].map[x][y]!=e[head].f&&e[head].map[x][y]!=0)
                          {
                              ++tail;
                              copy();
                              e[tail].map[x][y]=0;
                              if(e[head].f==1)
                            {
                                  e[tail].f=-1;
                                  e[tail].map[i][j]=-1;
                            }
                              else
                            {
                                e[tail].f=1;
                                e[tail].map[i][j]=1;
                            }
                              tep[tail]=tep[head]+1;
                              if(judge(tail))
                              {
                                  flag=1;
                                  ans=min(ans,tep[tail]);
                                  break;//手残打成return... 
                            }
                            if(check(e[tail])) tail--;
                        }
                    }
                }
                if(flag)break;
              }
        }
    }
    
    
    int main()
    {
        for(int i=1;i<=4;i++)
          for(int j=1;j<=4;j++)
          {
              char c;
              cin>>c;
              if(c=='W')mm[i][j]=1;
              else if(c=='B')mm[i][j]=-1;
              else mm[i][j]=0;
          }
        for(int k=1;k<maxn;k++)
          for(int i=1;i<=4;i++)
            for(int j=1;j<=4;j++)
            {
                e[1].map[i][j]=mm[i][j];
                e[k].f=0;
                tep[k]=0;
            }
        flag=0;ans=maxn;
        e[1].f=-1;
        Bfs();
        hash.clear();
        for(int k=1;k<maxn;k++)
          for(int i=1;i<=4;i++)
            for(int j=1;j<=4;j++)
            {
                e[1].map[i][j]=mm[i][j];
                e[k].f=0;
                tep[k]=0;
            }
        head=0;tail=1;flag=0;
        e[1].f=1;
        Bfs();//因为一开始走黑棋白棋结果可能不一样,所以两遍 
        printf("%d
    ",ans);
        return 0;
    }
    bfs
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    Project 01 PlantAndZomb
    iOS平台内存使用原则
    IOS之UIKit_Day22--23
    IOS之UIKit_Day21
    IOS之UIKit_Day20
    浅谈javascript数据类型,对象,类
    从输入一个url到加载页面发生了什么?
    d3.js(2)-svg
    d3.js(1)
    console.time和performance.now()
  • 原文地址:https://www.cnblogs.com/L-Memory/p/6413302.html
Copyright © 2011-2022 走看看