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
*/
posted @ 2023-01-09 10:53  PKU_IMCOMING  阅读(45)  评论(0)    收藏  举报