【CF1808C】Unlucky Numbers【类 数位DP】

56 篇文章 0 订阅
文章讨论了解决一个关于数位填充问题的算法,针对位数不同和位数相同两种情况,通过枚举和比较找到符合条件的数字。作者给出了C++代码示例并解释了关键步骤。
摘要由CSDN通过智能技术生成

在这里插入图片描述

分析

看着像数位DP,但是貌似状态不太好定义,而有一些特殊性质,于是用这种思想去做题,也就是枚举每一位填的数字去填,加上判定就行。

第一种情况,两个数位数不同,那一定可以找到一个位数与较短的一个相同的,幸运值为0的数。启示我们填数只需要记录位数较少的一个的位数就行。

第二种情况,位数相同。我们枚举数字的最大值和最小值,然后一位一位填。每填上一位的时候就把后面的全部“补齐”,具体就是全都补齐最小的那个数,然后与下界比较,补齐最大的那个数然后与上界比较。

如果比下界还小,那补齐用的数字可以继续增大,如果比上界还大,那证明与补齐无关,就是这一位填大了。直到有一个数可以满足这两个条件,那就确定为可以填的数。
如果一个数填好了出来就统计答案。

官方题解:
在这里插入图片描述

上代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;

ll t;
int a[20],b[20];
ll l,r,L,R,ans=20,anss;


int main()
{
	cin>>t;
	while(t--)
	{
		scanf("%lld%lld",&L,&R);
		if(L<10) 
		{
			cout<<L<<endl;
			continue;
		}
		int tot=0;
		l=L;
		while(L)
		{
			a[++tot]=L%10;
			L/=10;
		}
		for(int mn=0;mn<=9;mn++)
		{
			for(int mx=mn;mx<=9;mx++)
			{
				ll res=0;
				int ff;
				for(int i=1;i<=tot;i++)
				{
					ff=-1;
					for(int j=mn;j<=mx;j++)
				    {
				    	ll nowr=res*10+j;
				    	for(ll k=i+1;k<=tot;k++) nowr=nowr*10+mn;
				    	if(nowr>r) break;
				    	ll nowl=res*10+j;
				    	for(ll k=i+1;k<=tot;k++) nowl=nowl*10+mx; 
				    	if(nowl<l) continue;
				    	ff=j;
				    	break;
					}
					res=res*10+ff;
					if(res>=l&&res<=r)
					{
						if(ans>mx-mn)
						{
							ans=mx-mn;
							anss=res;
						}
					}
				}
				if(ff!=-1)
				{
					if(ans>mx-mn)
					{
						ans=mx-mn;
						anss=res;
					}
				}
			}
		}
		printf("%lld\n",anss);
		ans=20;
	}
	return 0;
}
/*一堆破烂代码,狗过去了,懒得改了,有空再改*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值