【洛谷2022】 神奇数学题

本文介绍了一种使用数位DP算法解决特定计数问题的方法。通过递推计算比当前数小的数的数量,并通过不断累加能够优化数量的位数来逼近目标值。该算法适用于求解数字串中满足特定条件的数的数量问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法过程:先算出比现在小的有多少个,和之后在末尾添加能够优化的数量分别记录为cnt,p;

然后因为每多一位P*10即可。

标程来自网络单纯叙述题解的解法。

//copy 标程 特注明 
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll N,M,K,cnt,base=1;
ll fj[21],s[21];
void get(ll x)
   {
        ll t=0; 
        while (x){s[++t]=x%10;x/=10;base*=10;}base/=10;
        for (int i=1;i<=t;i++) fj[i]=s[t-i+1];
        cnt+=t-1;
        for (int i=t;i>=1;i--)
          {
                ll sum=0;
                for (int j=1;j<=i;j++)
             if (j!=1)sum*=10,sum+=fj[j];
                  else sum*=10,sum+=fj[j],sum-=1;
                cnt+=sum;
          }
   }
   
int main()
   {
        cin>>K>>M;
        get(K);
        if (cnt>=M||(K==base&&cnt<M-1)) {cout<<0<<endl; return 0;}
        ll p=K-base,c=K;
        //cout<<p<<" "<<cnt<<endl;
        for (;cnt<M-1;)
           {
              p*=10;c*=10;
           cnt+=p;
           }
        //cout<<K<<" "<<c<<' '<<cnt-M+2<<endl;
        N=max(K,c-(cnt-M+2));
        cout<<N<<endl;
        return 0;
   }

   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值