• 棋盘游戏


    题目描述

    在一个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;
    }
    

      谁有出题人地址。

  • 相关阅读:
    Django 06. django框架模型之表关系ForeignKey,ManyToManyField与OneToOneField
    Django 05. django框架模型之models常用字段、属性及异常处理
    Django 04. django框架模型之生成数据表
    Django 03. django框架之路由系统
    Django 02. Django框架之基础
    Django 01. python Web 框架
    Python 操作 MySQL
    MySQL 常见数据类型
    MySQL 命令整理2
    MySQL 命令整理1
  • 原文地址:https://www.cnblogs.com/dai-jia-ye/p/9340966.html
Copyright © 2020-2023  润新知