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

    分析 Analysis

    搜索经典题

    这道题只是看上去很难= =

    首先我们要明确我们要做的事情:

    输入 判断胜局 行棋 状态储存 状态判重 

    其中行棋我们有:寻找行棋位 判断是否行棋 行棋

    对于状态,我们有:棋盘 序列码(Hash码) 步数 行棋方

    然后打一遍就过了= =

    代码 Code

      1 #include<cstdio>
      2 #include<queue>
      3 #include<iostream>
      4 #include<cstring>
      5 #define LL long long
      6 using namespace std;
      7 
      8 const int dir[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};
      9 int HASH[100000000];
     10 // State: Map Step Last HashCode?
     11 // Input:
     12 // Play: 
     13 //        FindSpace -> Move -> Hash? -> Check? -> Push
     14 //                                             -> Print
     15 // Check:
     16 //        X? -> Y? -> LU/RU?
     17 
     18 struct MAP{
     19     LL hashcode;
     20     int map[6][6],last,step;
     21     
     22     MAP(){
     23         memset(map,0,sizeof(map));
     24         last = step = hashcode = 0;
     25     }
     26 };
     27 
     28 queue<MAP> q;
     29 
     30 bool check(MAP now){
     31     for(int i = 1;i <= 4;i++)
     32     if(now.map[i][1] == now.map[i][2] && now.map[i][2] == now.map[i][3] && now.map[i][3] == now.map[i][4] ||
     33        now.map[1][i] == now.map[2][i] && now.map[2][i] == now.map[3][i] && now.map[3][i] == now.map[4][i]){
     34         return true;
     35     }
     36     
     37     if(now.map[1][1] == now.map[2][2] && now.map[2][2] == now.map[3][3] && now.map[3][3] == now.map[4][4] ||
     38        now.map[1][4] == now.map[2][3] && now.map[2][3] == now.map[3][2] && now.map[3][2] == now.map[4][1]){
     39         return true;       
     40     }
     41     
     42     return false;
     43 }
     44 
     45 bool GETCODE(MAP now){
     46     LL &code = now.hashcode;
     47     LL cnt = 1;
     48     for(int i = 1;i <= 4;i++){
     49         for(int j = 1;j <= 4;j++){
     50             code += now.map[i][j]*cnt;
     51             cnt *= 4;
     52         }
     53     }
     54     code += now.last*cnt;
     55     code %= 42137897;
     56     
     57     if(HASH[code]) return false;
     58     else{
     59         HASH[code] = 1;
     60         return true;
     61     }
     62 }
     63 
     64 void Input(){
     65     char ctmp;
     66     MAP sta;
     67     for(int i = 1;i <= 4;i++){
     68         for(int j = 1;j <= 4;j++){
     69             cin >> ctmp;
     70             switch(ctmp){
     71                 case 'B': sta.map[i][j] = 1; break;
     72                 case 'W': sta.map[i][j] = 2; break;
     73             }
     74         }
     75     }
     76     
     77     sta.step = 0;
     78     
     79     sta.last = 1;
     80     if(GETCODE(sta)) q.push(sta);
     81     sta.last = 2;
     82     if(GETCODE(sta)) q.push(sta);
     83 }
     84 
     85 void Move(MAP now,int x,int y){
     86     for(int i = 0;i < 4;i++){
     87         int nowx = x+dir[i][0];
     88         int nowy = y+dir[i][1];
     89         
     90         if(now.map[nowx][nowy] == now.last || !now.map[nowx][nowy]) continue;
     91         
     92         MAP cnt = now;
     93         
     94         cnt.map[x][y] = cnt.map[nowx][nowy];
     95         cnt.map[nowx][nowy] = 0;
     96         cnt.last = 3-now.last;
     97         cnt.step = now.step+1;
     98         
     99         if(GETCODE(cnt)) q.push(cnt);
    100     }
    101 }
    102 
    103 void Findspace(MAP now,int &x1,int &y1,int &x2,int &y2){
    104     for(int i = 1;i <= 4;i++){
    105         for(int j = 1;j <= 4;j++){
    106             if(!now.map[i][j]){
    107                 if(x1 == -1){
    108                     x1 = i,y1 = j;
    109                 }else{
    110                     x2 = i,y2 = j;
    111                 }
    112             }
    113         }
    114     }
    115 }
    116 
    117 void bfs(){
    118     while(!q.empty()){
    119         MAP tmp = q.front();
    120         q.pop();
    121         
    122         if(check(tmp)){
    123             if(!tmp.step) printf("1");
    124             else printf("%d",tmp.step);
    125             return;
    126         }
    127         
    128         int x1 = -1,x2 = -1,y1 = -1,y2 = -1;
    129         
    130         Findspace(tmp,x1,y1,x2,y2);
    131         
    132         Move(tmp,x1,y1);
    133         
    134         Move(tmp,x2,y2);
    135     }
    136 }
    137 
    138 int main(){
    139     
    140     Input();
    141     bfs();
    142     
    143     return 0;
    144 }
    = =心情很差
    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    Sqlite3:Sqlite3命令行Linux操作
    Docker:docker部署Sqlite3数据库
    SpringBoot:Sqlite3+SpringBoot2.1.3+Mybatis-Puls整合项目
    Algorithm:Java加密解密之MAC(消息认证码)
    Springboot:SpringBoot2.0整合WebSocket,实现后端数据实时推送!
    windows10系统安装anaconda后CMD命令行里面的python默认版本变化的问题
    在树莓派中,minicom的一些使用方法
    树莓派软硬串口对调
    树莓派无显示屏连接wifi教程
    设备管理器添加到桌面
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7325048.html
Copyright © 2011-2022 走看看