UVa 11212 编辑书籍 Editing a Book 迭代加深

主要思路来自于紫书,利用迭代加深的算法,一层一层往下搜,注意迭代加深的主体是bfs。所以每次的最大搜索层数maxd,都代表着0到maxd-1层都没有找到答案,所以,迭代加深相当于在maxd-1层的基础上又搜了一层(maxd层),这是典型的bfs,用来求最短路等问题(本题中求的是最少的剪切/粘贴次数)。

本题中,n的范围是1到9,所以搜索层数的范围就是1到8。

估价函数h()是这样确定的:每次剪切/粘贴最多改变三个数的后继(读者可以自己验证一下),也就是说,每搜一层,最多使三个数字的后继由错误变正确,所以,当(maxd - 当前层数)*3 < 当前错误后继数时,就应该剪枝。

#include <cstdio>
#include <cstring>
int a[30];
int kase = 1;
int n;

int hh()
{
	int cur = 0;
	for(int i = 1; i < n; i++)
		if(a[i+1] != a[i] + 1)  cur++;
	if(a[n] != n)  cur++;
	return cur;
}

bool dfs(int cur, int maxd)
{
	int h = hh();
	if(cur == maxd)  return h == 0;
	if(cur < maxd)  if(3*cur + h > 3*maxd + 1)  return false;
	int olda[30];
	int b[30];
	memcpy(olda, a, sizeof(a));
	for(int i = 1; i <= n; i++)                               // 剪切的左边界
	for(int j = i; j <= n; j++)                               // 剪切的右边界
	{
		int now = 1;
		for(int k = 1; k <= n; k++)
		if(k < i || k > j)  b[now++] = a[k];
		for(int d = 1; d <= now; d++)                     //剪下来的部分是a[i..j],剩下的部分是b[1..now-1],要把a[i..j]这个整体依次插入到b[1],b[2],..,b[now]的位置。
		{
			int now2 = 1;
			int ii = i;
			for(int p = d; p < d+j-i+1; p++)  a[p] = olda[ii++];
			for(int p = 1; p < d; p++)  a[p] = b[now2++];
			for(int p = d+j-i+1; ; p++)
			{
				//printf("p = %d i = %d j = %d n = %d\n",p,i,j,n);	
				a[p] = b[now2++]; 
				if(now2 > n-(j-i+1)) break;
			}
			if(dfs(cur+1, maxd)) return true;         //搜下一层
			memcpy(a, olda, sizeof(a));               //还原a数组
		}
	}
	return false;
}

int solve()
{
	int maxd_max = 8;
	for(int maxd = 0; maxd < 8; maxd++)
		if(dfs(0, maxd))  return maxd;
	return maxd_max;
}


int main()
{
	//freopen("ztest.txt","r",stdin);
	//freopen("zans.txt","w",stdout);
	while(scanf("%d",&n) && n)
	{
		for(int i = 1; i <= n; i++)
			scanf("%d",&a[i]);
		printf("Case %d: %d\n", kase++, solve());
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`draw_geometries_with_editing`是Open3D中用于可视化和编辑几何图形的函数。它允许您通过鼠标和键盘控制图形的旋转、平移、缩放等操作,以及添加、删除、修改点云和三维模型中的点、线、面等元素。 在使用`draw_geometries_with_editing`函数时,您需要按照以下步骤进行编辑: 1. 创建一个要编辑的几何图形对象,例如点云或三维模型。 2. 将该对象添加到一个列表中,并调用`draw_geometries_with_editing`函数进行可视化和编辑。 3. 在可视化窗口中,您可以使用鼠标和键盘控制图形的旋转、平移、缩放等操作。 4. 您可以使用鼠标右键添加、删除、选择等操作。例如,按住鼠标右键并拖动可以选择多个点,按下删除键可以删除所选点。 5. 在编辑完成后,您可以按下键盘上的“Q”键退出编辑模式,并获取编辑后的几何图形对象。 以下是一个简单的示例代码,演示如何使用`draw_geometries_with_editing`函数对点云进行编辑: ```python import open3d as o3d # 创建点云 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector([ [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1] ]) # 添加到列表并进行可视化和编辑 o3d.visualization.draw_geometries_with_editing([pcd]) # 获取编辑后的点云对象 edited_pcd = o3d.geometry.PointCloud() edited_pcd.points = pcd.points ``` 在这个示例中,我们创建了一个简单的点云,并将其添加到一个列表中进行可视化和编辑。在可视化窗口中,您可以使用鼠标和键盘进行编辑操作。编辑完成后,您可以按下键盘上的“Q”键退出编辑模式,并获取编辑后的点云对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值