16.数字生成游戏

作者:冰糖鸽子


一道不错的字符串+宽搜练手题


思路

首先显而易见的是,关于一个数字能到达的数字的最大长度,咱们分别看三个操作:

  • 操作1,位数不变
  • 操作2,位数减少
  • 操作3,位数加一,但不会超过初始数字的长度

所以可以得出结论:不管怎么变化,数字的长度都不会超过原数字的长度,也就是最大只能搜索到 99999 , 所以毫不犹豫用宽搜

而在宽搜中,第一次被搜到肯定是最佳答案,所以可以加上一个记忆化,复杂度降到 O(nm) ⁡ \operatorname{O(nm )} O(nm) , 其中 m m mwhile中运行一次需要的时间,在我的程序中, m m m 约是 l 3 ⁡ \operatorname{l^3} l3 l l l 是原数的位数

最多约需要 O(12500000) ⁡ \operatorname{O(12500000)} O(12500000) 的时间,完全可以在 1s 内跑出来

最后提一句,因为这三个操作需要插入,删除,交换什么的,所以我用了 string 来存储数字


代码

  • 细节说明:在开始把原数的答案设成 1 1 1 而不是 0 0 0 , 意味着所有可通过原数转换到的数的答案都大一,所以输出时要减一。而这样处理完后,不可通过原数转换到的数的答案在减一后就是 − 1 -1 1 , 正好符合题目要求

// Problem: P1132 数字生成游戏
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1132
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
int m,l;
string n;
map<string,int>ans;
queue<string>q;
void done()
{
	string u,v,f;
	int fl;
	q.push(n);
	while(!q.empty())
	{
		u=q.front();q.pop();fl=u.length();
		//cout<<u<<endl;
		//Step 1
		for(int i=0;i<fl;i++)
		{
			for(int j=i+1;j<fl;j++)
			{
				v=u;
				swap(v[i],v[j]);
				if(!ans[v])
				{
					ans[v]=ans[u]+1;
					q.push(v);
				}
				swap(v[i],v[j]);
			}
		}
		//Step 2
		for(int i=0;i<fl;i++)
		{
			v=u.substr(0,i)+u.substr(i+1);
			if(!ans[v])
			{
				ans[v]=ans[u]+1;
				q.push(v);
			}
		}
		// Step 3*
		if(u.length()<l)
		{
			for(int i=0;i<fl-1;i++)
			{
				for(char j=u[i]+1;j<u[i+1];j++)
				{
					v=u;
					f="";
					f+=j;
					v.insert(i+1,f);
					if(!ans[v])
					{
						ans[v]=ans[u]+1;
						q.push(v);
					}
				}
			}
		}
	}
}
int main()
{
	cin>>n;l=n.length();
	ans[n]=1;
	done();
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>n;
		cout<<ans[n]-1<<endl;
	}
	return 0;
}

本文链接:16.数字生成游戏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值