码迷,mamicode.com
首页 > 其他好文 > 详细

Codevs p1004 四子连棋

时间:2015-08-27 00:04:37      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:

                                               四子连棋

题目描述 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


思路分析: bfs+hash判重,记录每次走过的棋局,进行每条直线与对角线的判断(类似于八皇后的判断),记录下一步该走黑棋还是白棋。

 

我是看的hzw神犇的blog才会的,程序基本上是理解了照搬过来的,不建议看。hzw神犇的题解-->http://hzwer.com/848.html
程序:
技术分享
  1 #include <iostream>
  2 using namespace std;
  3 struct data
  4 {
  5     int map[5][5];
  6 }dt[5000];
  7 int next[5000]={1,2};
  8 int step[5000];
  9 bool haxi[4000000];
 10 int x1[4]={0,0,1,-1},
 11     y1[4]={1,-1,0,0};
 12 int t=0,w=2,f=0;
 13 int hash()
 14 {
 15     int k=1,s=0;
 16     for (int i=1;i<=4;i++)
 17       for (int j=1;j<=4;j++)
 18         {
 19             s+=dt[w].map[i][j]*k;
 20             k*=3;
 21         }
 22     s%=3733799;
 23     if (!haxi[s]) 
 24       {
 25           haxi[s]=1;
 26           return 1;
 27       }
 28     return 0;
 29 }
 30 bool pd4l(int a1,int b1,int c,int d)
 31 {
 32     if (a1!=b1||b1!=c||c!=d||a1!=d) return 0;
 33     return 1;
 34 }
 35 bool fnis()
 36 {
 37     for (int i=1;i<=4;i++)
 38       {
 39           if (pd4l(dt[w].map[i][1],dt[w].map[i][2],dt[w].map[i][3],dt[w].map[i][4])) return 1;
 40           if (pd4l(dt[w].map[1][i],dt[w].map[2][i],dt[w].map[3][i],dt[w].map[4][i])) return 1;
 41       }
 42     if (pd4l(dt[w].map[1][1],dt[w].map[2][2],dt[w].map[3][3],dt[w].map[4][4])) return 1;
 43     if (pd4l(dt[w].map[1][4],dt[w].map[2][3],dt[w].map[3][2],dt[w].map[4][1])) return 1;
 44     return 0;
 45 }
 46 void excg(int &a,int &b)
 47 {  int t;
 48    t=a;
 49    a=b;
 50    b=t;
 51 }
 52 bool pd(int x,int y)
 53 {   int k;
 54     k=next[t];
 55     if (x>4||x==0||y>4||y==0) return 0;
 56     else if (dt[t].map[x][y]==k) return 1;
 57     return 0;
 58 }
 59 void move(int x,int y)
 60 {
 61     int p,q;
 62     for (int i=0;i<4;i++)
 63       {
 64           p=x1[i]+x;
 65           q=y1[i]+y;
 66           if (pd(p,q))
 67             {
 68                 for (int j=1;j<=4;j++)
 69                   for (int k=1;k<=4;k++)
 70                     dt[w].map[j][k]=dt[t].map[j][k];
 71                 excg(dt[w].map[p][q],dt[w].map[x][y]);
 72                 step[w]=step[t]+1;
 73                 if (fnis()) {cout<<step[w]; f=1;return;}
 74                 if (hash()) 
 75                   {
 76                       
 77                   if (next[t]==1) next[w++]=2;
 78                   if (next[t]==2) next[w++]=1;
 79                   }
 80             }
 81       }
 82 }
 83 void search()
 84 {
 85     while (t<w)
 86       {
 87           for (int i=1;i<=4;i++)
 88             for (int j=1;j<=4;j++)
 89             {
 90               if (dt[t].map[i][j]==0)
 91                  move(i,j);
 92               if (f==1) return;
 93           }
 94           t++;
 95       }
 96 }
 97 int main()
 98 {
 99     char x;
100     for (int i=1;i<=4;i++)
101       for (int j=1;j<=4;j++)
102         {
103             cin>>x;
104             if (x==W) {dt[0].map[i][j]=dt[1].map[i][j]=1;}
105             if (x==B) {dt[0].map[i][j]=dt[1].map[i][j]=2;} 
106             // if (x==‘O‘) {dt[0].map[i][j]=dt[1].map[i][j]=0;} 
107         }
108      search();
109      return 0;
110 }
99%相同,题解是条不归路。

 

 

 

 

Codevs p1004 四子连棋

标签:

原文地址:http://www.cnblogs.com/DMonster/p/4761898.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!