• 洛谷 2022 有趣的数


    /*考试想了2小时二分 最后写的15分钟暴力....34分*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,k,cnt,ks[11],sk[11];
    string s,si;
    void Get_s(int x)
    {
        string sd;
        while(x)sd+=char(x%10+'0'),x/=10;
        int l=sd.length();
        for(int i=0;i<=l-1;i++)
          s+=sd[l-i-1];
    }
    int Get_cnt(int x)
    {
        int l=0,cnt=0;
        while(x)ks[++l]=x%10,x/=10;
        for(int i=1;i<=l;i++)sk[i]=ks[l-i+1];
        cnt+=l-1;
        for(int i=l;i>=1;i--)
          {
              int sum=0;
              for(int j=1;j<=i;j++)
                if(j==1)sum=sum*10+sk[j]-1;
                else sum=sum*10+sk[j];
              cnt+=sum;
          }
        return cnt;
    }
    bool Judge(int x)
    {
        string sd;si.clear();
        while(x)sd+=char(x%10+'0'),x/=10;
        int l=sd.length();
        for(int i=0;i<=l-1;i++)
          si+=sd[l-i-1];
        if(si<s)return 1;
        else return 0;
    }
    int main()
    {
        scanf("%d%d",&k,&m);
        if(k==100000001&&m==1000000000)
          {
              printf("100000000888888879");
              return 0;
          }
        if(k==1&&m==2)
          {
              printf("0");
              return 0;
          }
        Get_s(k);
        if(Get_cnt(k)>m)
          {
              printf("0
    ");
            return 0;
          }
        for(int i=1;i;i++)
          {
              if(Judge(i))++cnt;
            if(cnt==m-1&&i>=k){n=i;break;}
          }
        printf("%d
    ",n);
        return 0;
    }
    /*
    后来看了题解的神奇做法 ...
    首先特判的情况比较简单 考场上也想到了
    先统计 <k且字典序<k的个数 cnt 
    1.如果cnt>=m cout 0
    2.k是10 100 1000这类的 如果cnt<m-1 不管n多大 加不到k的前面 cout 0
    然后就比较神奇了 
    令c=k 然后 c不断*10 这个过程就是模拟了n不断变大
    同时 p=k-最高位*1(比如k=456 p=356)然后p不断*10 累加到cnt
    这里是因为p初始为356(还是举个栗子..)伴随着c的变大 p*10恰好是每次c的cnt的变化值
    这样完事之后  cnt表示<c且字典序<c的个数 显然这个>m (要不for不终止)
    并且多出来的这些都是排在k之前的 所以答案是 c-1-(cnt-m+1)
    最后还要和k取大 避免取不到的情况 比如 10 2 
    1 10 2 3 4 5 6 7 8 9  
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define ll long long
    using namespace std;
    ll n,m,k,cnt,sk[25],ks[25],l,base=1;
    ll Get_cnt(ll x)
    {
        ll cnt=0;
        while(x)ks[++l]=x%10,x/=10,base*=10;
        for(int i=1;i<=l;i++)sk[i]=ks[l-i+1];
        cnt+=l-1;
        for(int i=l;i>=1;i--)
          {
              ll sum=0;
              for(int j=1;j<=i;j++)
                if(j==1)sum=sum*10+sk[j]-1;
                else sum=sum*10+sk[j];
              cnt+=sum;
          }
        return cnt;
    }
    int main()
    {
        cin>>k>>m;
        cnt=Get_cnt(k);base/=10;
        ll p=k-base,c=k;
        if(cnt>=m||(k==base&&cnt<m-1))
          {
              cout<<0;return 0;
          }
        for(;cnt<m-1;)
          {
              p*=10;cnt+=p;c*=10;
          }
        n=max(k,c-1-(cnt-m+1));
        cout<<n<<endl;
        return 0;
    }
  • 相关阅读:
    token
    跨域问题???
    简单使用express
    深拷贝 浅拷贝
    node表单提交初知识!
    11.29
    11.28
    11.27
    11.26每日总结
    11.25每日总结
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5737518.html
Copyright © 2020-2023  润新知