棋盤游戲


題目描述

在一個4x4的棋盤上有8個黑棋和8個白棋,當且僅當兩個格子有公共邊時,這兩個格子上的棋是相鄰的。移動棋子的規則是交換相鄰的兩個棋子。現在給出一個初始棋盤和一個最終棋盤,要求你找出一個最短的移動序列使初始棋盤變為最終棋盤。

輸入

第一到第四行每行4個數字(1或者0),描述初始棋盤。

接着是一個空行。

第六道第九行每行4個數字,描述最終棋盤。

輸出

輸出文件的第一行是一個整數n,表示最少的移動步數。

樣例輸入

1111
0000
1110
0010

1010
0101
1010
0101

樣例輸出

4
在做這道題時我只想去賣武器。我們發現這到題要用搜索做,但我們發現用深搜要一個一個字符去存儲假設出題人想坑你,前幾次都沒有找到答案,那你可能時間早就炸了,槍賣好了嗎。那么我們只能用廣搜了,誒。
但是要怎么去搜呢:
1.我們發現只需要往上和往左去搜。
2.如何去標記棋盤是否走完。
那么第2問我們用二進制去記錄:
1111
1111
1111
1111
這個棋盤變為二進制為1111111111111111,十進制為65535,那么標記數組最大只要65536就可以了,將十進制轉二進制公式為:a=(1<<a)+ch-'0'。在i行j列的二進制為asn1=16-((i-1)*4+j),(有16個數)。
取出其中的一位為x=t2&(1<<ans1),y=t2&(1<<(ans+4)),用位運算去取最后一位(機智)。
代碼:
#include<bits/stdc++.h>
using namespace std;
struct str
{
	int qi_pan,ans;//記錄棋盤,ans為步數 
}a[1100000];
int b[1100000]={0},l,r,ans1,ans2;//b數組標記,ans1為初始棋盤的十進制的值,ans2為結束棋盤的值 
char ch;
void cin_1()
{
	
	for(int i=1;i<=4;i++)
	{
		for(int j=1;j<=4;j++)
		{
			cin>>ch;
			ans1=(ans1<<1)+ch-'0';//轉換 
		}
	}
	for(int i=1;i<=4;i++)
	{
		for(int j=1;j<=4;j++)
		{
			cin>>ch;
			ans2=(ans2<<1)+ch-'0';
		}
	}
	l=-1;
	a[r].qi_pan=ans1;//數組初始 
	a[r].ans=0;
}
void bfs()
{
	cin_1();//讀入 
	while(l<r)
	{
		str t=a[++l];//讀入隊頭 
		if(t.qi_pan==ans2)//判斷是否滿足條件 
		{
			cout<<t.ans<<endl;
			exit(0);
		}
		for(int i=2;i<=4;i++)//因為第一行無法向上交換 
		{
			for(int j=1;j<=4;j++)
			{
				int t2=t.qi_pan;
				int ans1=16-((i-1)*4+j);
				int x=t2&(1<<ans1);
				if(x>0) x=1;
				int y=t2&(1<<(ans1+4));
				if(y>0) y=1;
				if(x^y==1)
				{
					t2^=(1<<ans1);//為了回溯不出錯 
					t2^=(1<<(ans1+4));//置反 
					if(b[t2]==0)
					{
						b[t2]=1;//標記 
						r++;
						a[r].ans=t.ans+1;//步數++ 
						a[r].qi_pan=t2;//記錄當前棋盤 
					}
				}
			}
		}
		for(int i=1;i<=4;i++)
		{
			for(int j=2;j<=4;j++)//向左走,第一列不用 
			{
				int t2=t.qi_pan;//同上 
				int ans1=16-((i-1)*4+j);
				int x=t2&(1<<ans1);
				if(x>0) x=1;
				int y=t2&(1<<(ans1+1));//列數一定要加1 
				if(y>0) y=1;
				if(x^y)
				{
					t2^=(1<<ans1);//同上 
					t2^=(1<<(ans1+1));
					if(b[t2]==0)
					{
						b[t2]=1;
						r++;
						a[r].ans=t.ans+1;
						a[r].qi_pan=t2;
					}
				}
			}
		}
	}
}
int main()
{
	bfs();
	return 0;
}

  誰有出題人地址。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM