首页 > 其他分享 >2.八数码II(搜索进阶 IDA*估价函数 + 迭代加深)

2.八数码II(搜索进阶 IDA*估价函数 + 迭代加深)

时间:2023-05-03 16:33:06浏览次数:49  
标签:状态 return 进阶 int s1 网格 II IDA

八数码II

↑ 题目链接

题目

在一个 \(3×3\) 的网格中,\(1∼8\) 这 8 个数字和一个 X 恰好不重不漏地分布在这 \(3×3\) 的网格中。

例如:

1 2 3
X 4 6
7 5 8

在游戏过程中,可以把 X 与其上、下、左、右四个方向之一的数字交换(如果存在)。

把 X 与上下左右方向数字交换的行动记录为 u、d、l、r

现在,给你一个初始网格状态,并希望你将其变换为一个目标网格状态,请你找到所需行动次数最少的方案。

我们用一行字符串来描述一种网格状态。

例如,网格:

1 2 3 
X 4 6 
7 5 8 

123X46758 来表示。

输入格式

第一行包含整数 \(T\) ,表示共有 \(T\) 组测试数据。
每组数据占两行,第一行包含一个字符串表示初始网格状态,第二行包含一个字符串表示目标网格状态。
保证给定状态合法,并且一定有解。

输出格式

每组数据输出占两行,第一行输出 Case x: y,其中 x 为组别编号(从 1 开始),y为所需最少行动次数。
第二行输出具体行动方案,如果方案不唯一,则输出字典序最小的方案。

数据范围
\(1≤T≤200\)

输入样例:

2
12X453786
12345678X
564178X23
7568X4123

输出样例:

Case 1: 2
dd
Case 2: 8
urrulldr

思路

本题需要最小字典序,并且有多组样例。应该使用 \(IDA^{∗}\) 解题:

估值函数的选择:
  • 每个点与目标点曼哈顿距离差的和。

在何时选择 \(A^{∗}\) 或 \(IDA^{∗}\) :

  • 需要最小字典序时,状态表示很大,指数增长较快时,使用 \(IDA^{∗}\)
  • 若状态容易表示,指数增长较慢时,使用 \(A^{∗}\)(注意需要最小字典序时不能用 \(A^{∗}\) ,因为它不是按照顺序搜索的)
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
string s1,s2;
int pos[12];
int path[N];
string op="dlru";
int dx[]={1,0,0,-1};
int dy[]={0,-1,1,0};

//估值函数,当前状态和目标状态每个点的曼哈顿距离差的和
int f()
{
	int res=0;
	for(int i=0;i<9;i++)
	{
	    if(s1[i]!='X')
	    {
	        int num=s1[i]-'0';
	        res+=abs(i/3-pos[num]/3)+abs(i%3-pos[num]%3);
	    }
	}
	
	return res;
}

bool dfs(int u,int depth)
{
    //如果当前深度 + 估值深度 > 最大深度,直接回溯
	if(f()+u>depth)return false;
	
	//找到答案,返回true
	if(s1==s2)return true;
	
	
	//存X当前的位置序号
	int k;
	for(int i=0;i<9;i++)
		if(s1[i]=='X')
		{
			k=i;
			break;
		}
	
	int x=k/3,y=k%3;
	
	for(int i=0;i<4;i++)
	{
		int a=x+dx[i],b=y+dy[i];
		if(a<0||a>=3||b<0||b>=3)continue;
		
		 //避免往回走(至少走了1步,且上一步和当前一步和为3)
        //d+u=0+3=3  l+r=1+2=3
        //下(d):0 左(l):1 右(r):2 上(u):3
		if(u>0&&i+path[u-1]==3)continue;
		
		swap(s1[k],s1[a*3+b]);
		path[u]=i;//保存路径
		
		if(dfs(u+1,depth))return true;//找到答案,一路返回true
		swap(s1[k],s1[a*3+b]);
	}
	
	
	return false;
}

int main()
{
	int T;
	cin>>T;
	for(int i=1;i<=T;i++)
	{
		cin>>s1>>s2;
		
		for(int i=0;i<9;i++)
			if(s2[i]!='X')
				pos[s2[i]-'0']=i;
		
		 //迭代加深IDA*
		int depth=0;
		while(!dfs(0,depth))depth++;
		
		printf("Case %d: %d\n",i,depth);
		
		for(int i=0;i<depth;i++)
			printf("%c",op[path[i]]);
		
		puts("");
	}
	
	
	return 0;
}

标签:状态,return,进阶,int,s1,网格,II,IDA
From: https://www.cnblogs.com/zzmxj/p/17369226.html

相关文章

  • 1.八数码 (搜索进阶 BFS)
    八数码题目在一个\(3×3\)的网格中,\(1∼8\)这\(8\)个数字和一个\(X\)恰好不重不漏地分布在这\(3×3\)的网格中。例如:123X46758在游戏过程中,可以把X与其上、下、左、右四个方向之一的数字交换(如果存在)。我们的目的是通过交换,使得网格变为如下排列(称为正......
  • Intel Pentium III 512MB内存 i815集显上安装Ubuntu Server 14.04
    自己的御用奔腾IIIPC,接口齐全,准备安装UbuntuServer14.04i386,继续发挥余热,物尽其用。 基本配置:CPU:IntelPentiumIII1000MHz,256KBL2,133MHzFSB,0.18um,1.75v,Coppermine-TRAM:512MBSDRAM,PC133GPU:Inteli82815IGPHDD:128GBSSD, withSATAtoIDEa......
  • 剑指 Offer II 022. 链表中环的入口节点
    题目链接:剑指OfferII022.链表中环的入口节点方法一:哈希解题思路统计走过的节点,当第一次遇到重复的节点时,即为入口节点,否则为\(null\)。代码classSolution{public:ListNode*detectCycle(ListNode*head){unordered_map<ListNode*,bool>cache;......
  • 23 IIC(一)IIC协议简介
    1硬件连接IIC硬件接线一般如下所示。从主控芯片引出两根线SCL和SDA。外加一个上拉电阻2数据传输格式2.1写操作主控芯片发出start信号主控芯片发出一字节的数据。前7bit为设备地址,最后一bit为方向:0表示写,1表示读主设备等待从设备应答主设备接到从设备的应答后开始发送......
  • 剑指 Offer II 020. 回文子字符串的个数
    题目链接:剑指OfferII020.回文子字符串的个数方法一:动态规划解题思路状态表示:\(dp[i][j]\)表示子字符串\(s[i,j]\)是否为回文串;状态计算:若\(s[i]\)!=\(s[j]\),显然不是;若\(s[i]\)==\(s[j]\),有以下几种可能:\(i\)==\(j\),只有一个字符,是回文串;\(i\)+\(1\)......
  • caidao——wp——qsnctf
    进入网页发现如下内容直接使用蚁剑连接连接并进入后,在根目录下发现名为flag的文件,即可获取flag-End-......
  • 【剑指 Offer】 14- II. 剪绳子 II
    【题目】给你一根长度为n的绳子,请把绳子剪成整数长度的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1]...k[m-1]。请问k[0]*k[1]*...*k[m-1]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。答案需要......
  • FAST-LIO:A Fast,Roust LiDAR-inertial Odometry Package by Tightly-Coupled Iterate
    摘要——本文提出一种计算高效、鲁棒的激光雷达惯性里程计框架。我们使用紧耦合的迭代扩展卡尔曼滤波器将激光雷达特征点与IMU数据融合,以允许在发生退化的快速运动、噪声或者杂乱环境中进行稳健导航。为了在出现大量观测情况下降低计算负载,我们提出了一个计算卡尔曼增益的新公式。......
  • 当前标识(IIS APPPOOL\XX)没有对“C:\Windows\Microsoft.NET\Framework64\4.0.30
    当前标识(IISAPPPOOL\WMS.APP)没有对“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\TemporaryASP.NETFiles”的写访问权限。解决此问题为在使用Windows的IIS搭建服务器时,遇到的问题。在网上尝试了各种解决方法后,终于找到了一个可以解决问题的方法,以管理员身份运行命令......
  • SpringBoot项目使用 validation进行数据校验
    validation进行数据校验@Validated注解和@Valid注解都是SpringFramework中用于数据校验的注解,但它们有以下几点区别:所在包路径不同:@Valid注解位于javax.validation.constraints包下,而@Validated注解位于org.springframework.validation.annotation包下。支持......