zoukankan      html  css  js  c++  java
  • 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

    数据范围及提示 Data Size & Hint

    hi

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 int xx[5] = {0,0,0,1,-1};        //枚举四个方向 
     6 int yy[5] = {0,1,-1,0,0};
     7 int map[5][5],minn = 1000;        //利用数组代表“黑、白、空” minn代表所求的最小步数 
     8 char s;
     9 void Dfs(int x,int y,int num,int b)    //b表示 先走那种颜色 
    10 {
    11     int m = 100000,i,j,k;
    12     if(num >= minn) 
    13         return;                 //剪枝 如果已经比目前的最优解大了 就不用再Dfs了 
    14     for(i = 1;i <= 4;i ++)        //4种目标棋局一一列举 如果有符合的 更新m的值 
    15     {
    16         if(map[i][1] == map[i][2] && map[i][2] == map[i][3] && map[i][3] == map[i][4] && (map[i][4] == 1 || map[i][4] == 2))//行相同更新 
    17         m = num;
    18         if(map[1][i] == map[2][i] && map[2][i] == map[3][i] && map[3][i] == map[4][i] && (map[4][i] == 1 || map[4][i] == 2))//列相同更新 
    19         m = num;
    20     }
    21     if(map[1][1] == map[2][2] && map[2][2] == map[3][3] && map[3][3] == map[4][4] && (map[4][4]==1 || map[4][4] == 2))//左上到右下相同更新 
    22         m = num;
    23     if(map[4][1] == map[3][2] && map[3][2] == map[2][3] && map[2][3] == map[1][4] && (map[1][4]==1 || map[1][4] == 2))//右上到左下相同更新 
    24         m = num;
    25     if(m < minn)            //m在上面已经更新为当前接了 这里用m更新minn 
    26     {
    27         minn = m;
    28         return;                //不用往后搜索了 因为后面不如现在优 
    29     }
    30     for(i = 1;i <= 4;i ++)
    31     {
    32         int tx = x + xx[i];        //横坐标更新
    33         int ty = y + yy[i];        //纵坐标更新
    34         if(tx > 0 && tx <= 4 && ty > 0 && ty <= 4 && map[tx][ty] == b)        //边界判断 
    35         {
    36             map[x][y] = map[tx][ty];
    37             map[tx][ty] = 0;        //走完之后map[tx][ty]变空  map[x][y]变map[tx][ty]
    38             if(b == 1)
    39             b = 2;                //黑白交替走 上次走黑 下次走白 
    40             else b = 1;
    41             for(j = 1;j <= 4;j ++)        //因为空格又不止一个 所以 找空格 
    42             for(k = 1;k <= 4;k ++)
    43             if(!map[j][k])        //空格的值为0 
    44                 Dfs(j,k,num+1,b);
    45             map[tx][ty] = map[x][y];        //回溯 
    46             map[x][y] = 0;
    47             if(b == 1)  b = 2;
    48             else    b = 1;
    49         }
    50     }
    51 }
    52 int main()
    53 {
    54     int i,j;
    55     for(i = 1;i <= 4;i ++)
    56     for(j = 1;j <= 4;j ++)
    57     {
    58         cin >> s;
    59         if(s == 'W') map[i][j] = 1;        //白棋 
    60         if(s == 'B') map[i][j] = 2;        //黑棋 
    61     }
    62     for(i = 1;i <= 4;i ++)
    63     for(j = 1;j <= 4;j ++)
    64     if(!map[i][j])        //空格 
    65     {
    66         Dfs(i,j,0,1);        //先走白棋 
    67         Dfs(i,j,0,2);        //先走黑棋 
    68     }
    69     cout<<minn<<endl;
    70     return 0;
    71 }
  • 相关阅读:
    POJ 2253 Frogger(最短路 Floyd)
    POJ 1062 昂贵的聘礼 (最短路 Dijkstra)
    POJ 3259 Wormholes(最短路Bellman_Ford)
    POJ 3414 Pots(容量BFS)
    POJ 3087 Shuffle'm Up(模拟题)
    POJ 3216 Prime Path(数字BFS)
    refresh的停车场
    基于邻接表的广度优先搜索遍历
    判断给定图是否存在合法的拓扑排序
    威威猫系列故事——篮球梦
  • 原文地址:https://www.cnblogs.com/mjtcn/p/6749268.html
Copyright © 2011-2022 走看看