Codevs 1004 四子连棋

Posted り挽歌、花开花落的流年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

数据范围及提示 Data Size & Hint

hi

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define Mod 9875321
 7 #define maxn 1000005
 8 long long read(){
 9     long long x=0,f=1;char ch=getchar();
10     while(ch<0||ch>9){
11         if(ch==-)f=-1;ch=getchar();
12     }
13     while(ch>=0&&ch<=9){
14         x=x*10+ch-0;ch=getchar();
15     }
16     return x*f;
17 }
18 int head=0,tail=2,ans=-1;
19 int step[maxn],xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
20 char q[maxn][5][5],a[5][5];
21 bool last[maxn],mp[maxn*10];
22 bool Valid(int x,int y,int t){
23     //该函数用于判断与空白格子交换的合法性
24     if(x>4||y>4||x<1||y<1||a[x][y]==O)return 0;
25     if(a[x][y]==B&&t==0)return 0;
26     if(a[x][y]==W&&t==1)return 0;
27     return 1;
28 }
29 bool equal(char a,char b,char c,char d){
30     if(a!=b || b!=c || c!=d)return 0;
31     return 1;
32 }
33 int gethash(char a[5][5]){
34     int t=0,key=0;
35     for(int i=1;i<=4;i++)
36       for(int j=1;j<=4;j++){
37           if(a[i][j]==O)t=0;
38           if(a[i][j]==W)t=1;
39           if(a[i][j]==B)t=2;
40           key=(key*3+t) % Mod;
41       }
42     return key;
43 }
44 bool check(char a[5][5]){
45     for(int i=1;i<=4;i++){
46         if(equal(a[i][1],a[i][2],a[i][3],a[i][4]))return 1;
47         if(equal(a[1][i],a[2][i],a[3][i],a[4][i]))return 1;
48     }
49     if(equal(a[1][1],a[2][2],a[3][3],a[4][4]))return 1;
50     if(equal(a[1][4],a[2][3],a[3][2],a[4][1]))return 1;
51     return 0;
52 }
53 void Move(int x,int y){
54     for(int k=0;k<4;k++){
55         int tx=x+xx[k],ty=y+yy[k];
56         if(!Valid(tx,ty,last[head]))continue;
57         
58         for(int i=1;i<=4;i++)
59           for(int j=1;j<=4;j++)
60             a[i][j]=q[head][i][j];
61             
62         swap(a[x][y],a[tx][ty]);
63         if(mp[gethash(a)])continue;
64         mp[gethash(a)]=1;
65         tail++;
66         for(int i=1;i<=4;i++)
67           for(int j=1;j<=4;j++)
68             q[tail][i][j]=a[i][j];
69         
70         step[tail]=step[head]+1;
71         last[tail]=last[head]^1;
72         if(check(a))ans=step[tail];
73     }
74 }
75 void BFS(){
76     while(head != tail){
77         for(int i=1;i<=4;i++)
78           for(int j=1;j<=4;j++)
79             if(q[head][i][j]==O)
80               Move(i,j);
81         if(ans != -1) return;
82         head++;
83     }
84 }
85 int main()
86 {
87     for(int i=1;i<=4;i++)
88       scanf("%s",a[i]+1);
89     for(int i=1;i<=4;i++)
90       for(int j=1;j<=4;j++)
91         q[0][i][j]=q[1][i][j]=a[i][j];
92         
93     last[0]=0;last[1]=1;
94     BFS();
95     printf("%d\n",ans);
96     return 0;
97 }

 

以上是关于Codevs 1004 四子连棋的主要内容,如果未能解决你的问题,请参考以下文章

codevs 1004 四子连棋

codevs1004四子连棋[BFS 哈希]

CODEVS——T 1004 四子连棋

CODEVS 1004四子连棋

迭代加深搜索[codevs1004 四子连棋]

宽度优先搜索神奇的状态压缩 CodeVs1004四子连棋