P2346
四子连棋
题目描述
在一个 \(4\times 4\) 的棋盘上摆放了 \(14\) 颗棋子,其中有 \(7\) 颗白色棋子,\(7\) 颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
\[\begin{array}{|c|c|c|c|}\hline
\text{●}&\text{○}&\text{●}&\text{} \cr \hline
\text{○}&\text{●}&\text{○}&\text{●}\cr\hline
\text{●}&\text{○}&\text{●}&\text{○}\cr\hline
\text{○}&\text{●}&\text{○}&\text{} \cr \hline
\end{array}\]
输入格式
从文件中读入一个 \(4\times 4\) 的初始棋局,黑棋子用 B 表示,白棋子用 W 表示,空格地带用 O 表示。
输出格式
用最少的步数移动到目标棋局的步数。
样例 #1
样例输入 #1
BWBO
WBWB
BWBW
WBWO
样例输出 #1
5
当你选择了用最朴素 最暴力的方法做这题时 就注定有一堆bug!!!
比如说我TMD有一个swap p1,p2打反……
这就 一袋茶 一包烟 一个bug调一天呗
警示!!!细节!!!
超长代码
#include<bits/stdc++.h>
using namespace std;
string start;
struct did{
int c;
string now;
int pd;//pd :0 black now 1 white now
}z;
int minn=INT_MAX;
bool check(string s)
{
if((s[0]=='W'&&s[1]=='W'&&s[2]=='W'&&s[3]=='W')||(s[0]=='B'&&s[1]=='B'&&s[2]=='B'&&s[3]=='B'))return true;
if((s[4]=='W'&&s[5]=='W'&&s[6]=='W'&&s[7]=='W')||(s[4]=='B'&&s[5]=='B'&&s[6]=='B'&&s[7]=='B'))return true;
if((s[8]=='W'&&s[9]=='W'&&s[10]=='W'&&s[11]=='W')||(s[8]=='B'&&s[9]=='B'&&s[10]=='B'&&s[11]=='B'))return true;
if((s[12]=='W'&&s[13]=='W'&&s[14]=='W'&&s[15]=='W')||(s[12]=='B'&&s[13]=='B'&&s[14]=='B'&&s[15]=='B'))return true;
if((s[0]=='W'&&s[4]=='W'&&s[8]=='W'&&s[12]=='W')||(s[0]=='B'&&s[4]=='B'&&s[8]=='B'&&s[12]=='B'))return true;
if((s[1]=='W'&&s[5]=='W'&&s[9]=='W'&&s[13]=='W')||(s[1]=='B'&&s[5]=='B'&&s[9]=='B'&&s[13]=='B'))return true;
if((s[2]=='W'&&s[6]=='W'&&s[10]=='W'&&s[14]=='W')||(s[2]=='B'&&s[6]=='B'&&s[10]=='B'&&s[14]=='B'))return true;
if((s[3]=='W'&&s[7]=='W'&&s[11]=='W'&&s[15]=='W')||(s[3]=='B'&&s[7]=='B'&&s[11]=='B'&&s[15]=='B'))return true;
if((s[0]=='W'&&s[5]=='W'&&s[10]=='W'&&s[15]=='W')||(s[0]=='B'&&s[5]=='B'&&s[10]=='B'&&s[15]=='B'))return true;
if((s[3]=='W'&&s[6]=='W'&&s[9]=='W'&&s[12]=='W')||(s[3]=='B'&&s[6]=='B'&&s[9]=='B'&&s[12]=='B'))return true;
return false;
}
void bfs2()
{
queue<did>q;set<string>st;
z.c=0,z.now=start,z.pd=0;
q.push(z);st.insert(start);
while(!q.empty())
{
z=q.front();
q.pop();
string s=z.now;
if(check(s))
{
// cout<<s<<"\n";
minn=min(minn,z.c);
return ;
}
int p1=-1,p2=-1;
for(int i=0;i<16;i++)
if(s[i]=='O')
{
if(p1==-1)p1=i;
else p2=i;
}
if(z.pd==0)
{
int x,y;
y=p1%4;
x=(p1-y)/4+1;
y++;
// cout<<x<<" "<<y<<" ";
if(x-1>=1&&s[p1-4]=='W')
{
string a=s;
swap(a[p1],a[p1-4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(x+1<=4&&s[p1+4]=='W')
{
string a=s;
swap(a[p1],a[p1+4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(y-1>=1&&s[p1-1]=='W')
{
string a=s;
swap(a[p1],a[p1-1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(y+1<=4&&s[p1+1]=='W')
{
string a=s;
swap(a[p1],a[p1+1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
y=p2%4;
x=(p2-y)/4+1;
y++;
// cout<<x<<" "<<y<<"\n";
if(x-1>=1&&s[p2-4]=='W')
{
string a=s;
swap(a[p2],a[p2-4]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(x+1<=4&&s[p2+4]=='W')
{
string a=s;
// cout<<a<<" ";
swap(a[p2],a[p2+4]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(y-1>=1&&s[p2-1]=='W')
{
string a=s;
// cout<<a<<" ";
swap(a[p2],a[p2-1]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(y+1<=4&&s[p2+1]=='W')
{
string a=s;
swap(a[p2],a[p2+1]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
// cout<<"\n";
}
if(z.pd==1)
{
int x,y;
y=p1%4;
x=(p1-y)/4+1;
y++;
if(x-1>=1&&s[p1-4]=='B')
{
string a=s;
swap(a[p1],a[p1-4]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(x+1<=4&&s[p1+4]=='B')
{
string a=s;
swap(a[p1],a[p1+4]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(y-1>=1&&s[p1-1]=='B')
{
string a=s;
swap(a[p1],a[p1-1]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(y+1<=4&&s[p1+1]=='B')
{
string a=s;
swap(a[p1],a[p1+1]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
y=p2%4;
x=(p2-y)/4+1;
y++;
if(x-1>=1&&s[p2-4]=='B')
{
string a=s;
swap(a[p2],a[p2-4]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(x+1<=4&&s[p2+4]=='B')
{
string a=s;
// cout<<a<<" ";
swap(a[p2],a[p2+4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(y-1>=1&&s[p2-1]=='B')
{
string a=s;
swap(a[p2],a[p2-1]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(y+1<=4&&s[p2+1]=='B')
{
string a=s;
swap(a[p2],a[p2+1]);
// cout<<a<<" ";
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
// cout<<"\n";
}
}
}
void bfs1()
{
queue<did>q;set<string>st;
z.c=0,z.now=start,z.pd=0;
q.push(z);st.insert(start);
while(!q.empty())
{
z=q.front();
q.pop();
string s=z.now;
if(check(s))
{
// cout<<s<<"\n";
minn=min(minn,z.c);
return ;
}
int p1=0,p2=0;
for(int i=0;i<16;i++)
if(s[i]=='O')
{
if(!p1)p1=i;
else p2=i;
}
if(z.pd==0)
{
int x,y;
y=p1%4;
x=(p1-y)/4+1;
y++;
if(x-1>=1&&s[p1-4]=='B')
{
string a=s;
swap(a[p1],a[p1-4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(x+1<=4&&s[p1+4]=='B')
{
string a=s;
swap(a[p1],a[p1+4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(y-1>=1&&s[p1-1]=='B')
{
string a=s;
swap(a[p1],a[p1-1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(y+1<=4&&s[p1+1]=='B')
{
string a=s;
swap(a[p1],a[p1+1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
y=p2%4;
x=(p2-y)/4+1;
y++;
if(x-1>=1&&s[p2-4]=='B')
{
string a=s;
swap(a[p2],a[p2-4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(x+1<=4&&s[p2+4]=='B')
{
string a=s;
swap(a[p2],a[p2+4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(y-1>=1&&s[p2-1]=='B')
{
string a=s;
swap(a[p2],a[p2-1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
if(y+1<=4&&s[p2+1]=='B')
{
string a=s;
swap(a[p2],a[p2+1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=1;q.push(d);
st.insert(a);
}
}
}
if(z.pd==1)
{
int x,y;
y=p1%4;
x=(p1-y)/4+1;
y++;
if(x-1>=1&&s[p1-4]=='W')
{
string a=s;
swap(a[p1],a[p1-4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(x+1<=4&&s[p1+4]=='W')
{
string a=s;
swap(a[p1],a[p1+4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(y-1>=1&&s[p1-1]=='W')
{
string a=s;
swap(a[p1],a[p1-1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(y+1<=4&&s[p1+1]=='W')
{
string a=s;
swap(a[p1],a[p1+1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
y=p2%4;
x=(p2-y)/4+1;
y++;
if(x-1>=1&&s[p2-4]=='W')
{
string a=s;
swap(a[p2],a[p2-4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(x+1<=4&&s[p2+4]=='W')
{
string a=s;
swap(a[p2],a[p2+4]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(y-1>=1&&s[p2-1]=='W')
{
string a=s;
swap(a[p2],a[p2-1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
if(y+1<=4&&s[p2+1]=='W')
{
string a=s;
swap(a[p2],a[p2+1]);
if(!st.count(a))
{
did d;d.c=z.c+1;d.now=a;d.pd=0;q.push(d);
st.insert(a);
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
char ch;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
{
cin>>ch;
start+=ch;
}
bfs1();
bfs2();
cout<<minn<<"\n";
return 0;
}
/*
BBWO
WBWB
BWBW
WBWO
*/
此生无悔入OI 来生AK IOI

浙公网安备 33010602011771号