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

    题目描述

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

    ● ○ ●

    ○ ● ○ ●

    ● ○ ● ○

    ○ ● ○

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    BWBO
    WBWB
    BWBW
    WBWO
    输出样例#1:
    5

    思路:深度优先搜索+特殊的状态储存。

    我是用二的幂储存的状态。

    因为是很早以前的代码了,我有点看不懂。

    另外黑白棋子谁先手是有影响的。

    有关黑棋的变量应该都一个字母‘b’,同样有关白棋的有一个‘w’,行是‘h’,列是‘l’。

    代码实现:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 int ww,bb,ans=300;
     6 int w[7][2],b[7][2],h[4];
     7 int hb[]={-1,0,1,0},lb[]={0,1,0,-1};//行变和列变。
     8 int ew[]={2,4,8,16},eb[]={32,64,128,256};
     9 char ch;
    10 void dfs(int step,int x){
    11     if(step>ans) return;
    12     if(step>0){
    13     for(int i=0;i<4;i++)
    14     if(h[i]==30||h[i]==480){ans=step;return;}
    15     for(int i=0;i<4;i++){
    16         if(h[0]&ew[i]&&h[1]&ew[i]&&h[2]&ew[i]&&h[3]&ew[i]){ans=step;return;}
    17         if(h[0]&eb[i]&&h[1]&eb[i]&&h[2]&eb[i]&&h[3]&eb[i]){ans=step;return;}
    18     }
    19     for(int i=0;i<5;i++){
    20         if(i==4){ans=step;return;}
    21         if(!(h[i]&ew[i])) break;
    22     }
    23     for(int i=0;i<5;i++){
    24         if(i==4){ans=step;return;}
    25         if(!(h[i]&ew[3-i])) break;
    26     }
    27     for(int i=0;i<5;i++){
    28         if(i==4){ans=step;return;}
    29         if(!(h[i]&eb[i])) break;
    30     }
    31     for(int i=0;i<5;i++){
    32         if(i==4){ans=step;return;}
    33         if(!(h[i]&eb[3-i])) break;//注意逻辑运算与或非的优先度。 
    34     }
    35     }
    36     if(x!=1){//移白棋 。 
    37         for(int i=0;i<7;i++)
    38         for(int j=0;j<4;j++){
    39             int ah=w[i][0],bl=w[i][1];
    40             int nh=ah+hb[j],nl=bl+lb[j];
    41             if((!(h[nh]&ew[nl]))&&(!(h[nh]&eb[nl]))&&nh>=0&&nh<4&&nl>=0&&nl<4){
    42                 h[nh]+=ew[nl];h[ah]-=ew[bl];
    43                 w[i][0]=nh;w[i][1]=nl;
    44                 dfs(step+1,1);
    45                 h[nh]-=ew[nl];h[ah]+=ew[bl];
    46                 w[i][0]=ah;w[i][1]=bl;
    47             }
    48         }
    49     }
    50     if(x!=0){//移黑棋。 
    51         for(int i=0;i<7;i++)
    52         for(int j=0;j<4;j++){
    53             int ah=b[i][0],bl=b[i][1];
    54             int nh=ah+hb[j],nl=bl+lb[j];
    55             if((!(h[nh]&ew[nl]))&&(!(h[nh]&eb[nl]))&&nh>=0&&nh<4&&nl>=0&&nl<4){
    56                 h[nh]+=eb[nl];h[ah]-=eb[bl];
    57                 b[i][0]=nh;b[i][1]=nl;
    58                 dfs(step+1,0);
    59                 h[nh]-=eb[nl];h[ah]+=eb[bl];
    60                 b[i][0]=ah;b[i][1]=bl;
    61             }
    62         }
    63     }
    64 }
    65 int main(){
    66     for(int i=0;i<4;i++)
    67     for(int j=0;j<4;j++){
    68         cin>>ch;
    69         if(ch=='W'){
    70             h[i]+=ew[j];
    71             w[ww][0]=i;w[ww++][1]=j;
    72         }
    73         if(ch=='B'){
    74             h[i]+=eb[j];
    75             b[bb][0]=i;b[bb++][1]=j;
    76         }
    77     }
    78     dfs(0,2);//这里是2,所以黑棋先手白棋先手各一遍。
    79     printf("%d
    ",ans);
    80     return 0;
    81 }

    题目来源:洛谷

  • 相关阅读:
    java实现第六届蓝桥杯立方体自身
    Java实现第八届蓝桥杯包子凑数
    Snapshot Standby
    [NOI2014]购票
    DG的数据保护模式
    严格次小生成树
    Java实现第八届蓝桥杯拉马车
    Java实现第八届蓝桥杯拉马车
    Java实现第八届蓝桥杯迷宫
    在物理 Data Guard 中对异构主备系统的支持 (文档 ID 1602437.1)
  • 原文地址:https://www.cnblogs.com/J-william/p/6443754.html
Copyright © 2011-2022 走看看