zoukankan      html  css  js  c++  java
  • 有趣的数

    让我们来考虑1到N的正整数集合。让我们把集合中的元素按照字典序排列,例如当N=11时,其顺序应该为:1,10,11,2,3,4,5,6,7,8,9。

    定义K在N个数中的位置为Q(N,K),例如Q(11,2)=4。现在给出整数K和M,要求找到最小的N,使得Q(N,K)=M。

    输入输出格式

    输入格式:

    输入文件只有一行,是两个整数K和M。

    输出格式:

    输出文件只有一行,是最小的N,如果不存在这样的N就输出0。

    对于一个k,一位数在它前面的数是固定的,两位数在它前面的数是固定的,可以计算

    而且,在k之前的数至少有一个定值,这是n取到k就有的

    所以只用计算大于k的情况

    比如354

    1000->3539

    10000->35399

    不要忘记m是第几位,而不是前几位

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long ll;
     8 const ll maxn=27;
     9 ll ans,k,m,len;
    10 ll fa[maxn];
    11 char s[maxn];
    12 ll getnum(ll x){
    13   sprintf(s,"%lld",x);
    14   len=strlen(s);
    15   ll num=0,ret=0;
    16   for(ll i=0;i<len;i++){
    17     num=num*10+s[i]-'0'; 
    18     ret+=num-fa[i]+1; 
    19   }
    20   return ret;
    21 }//这个方法要记住
    22 int main(){
    23   cin>>k>>m;
    24   fa[0]=1;for(ll i=1;i<=20;i++) fa[i]=fa[i-1]*10;
    25   for(ll i=0;i<=10;i++){
    26     if(k==fa[i]){
    27       if(m!=i+1){cout<<0<<endl;return 0;}
    28       if(m==i+1){cout<<k<<endl;return 0;}
    29     }
    30   } 
    31   ll tt=getnum(k);
    32   if(tt>m){cout<<0<<endl;return 0;}
    33   if(tt==m){cout<<k<<endl;return 0;}
    34   m-=tt;ans=fa[len];
    35   for(ll i=1;;i++){
    36     ll t=k*fa[i]-1-fa[i+len-1]+1;
    37     if(m>t){
    38       m-=t;ans*=10;
    39     }
    40     else break;
    41   }
    42   ans+=m-1;cout<<ans<<endl;
    43   return 0;
    44 }

    而我想到的打表,首先没有分析出k前面的数至少有一个定值的性质

    并且还错误的认为m<k-1就不可能,事实上是有可能的,并且很可能

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long ll;
     8 const int maxn=107;
     9 ll n,m,k,tot,mm,ans;
    10 ll num[maxn],cnt[maxn];
    11 ll getnum(ll x){
    12   int ret;
    13   while(x){
    14     x/=10;ret++;
    15   }ret--;
    16   return ret;
    17 }
    18 ll qpow(ll a,ll b){
    19   ll ret=1;
    20   for(;b;b>>=1,a*=a){
    21     if(b&1) ret*=a;
    22   }
    23   return ret;
    24 }
    25 void gettable(){
    26   ll tmp=1;
    27   for(ll i=1;i<=19;i++){
    28       if(i==mm){
    29       num[i]=k/(qpow(10,mm-i))-1;
    30       cnt[i]=num[i]-tmp+1;   
    31     }
    32     else if(tmp<k){
    33       num[i]=k/(qpow(10,mm-i));
    34       cnt[i]=num[i]-tmp+1;
    35     }
    36     else{
    37       num[i]=num[i-1]*10+9;
    38       cnt[i]=num[i]-tmp+1;
    39     }
    40     tmp*=10;
    41   }
    42 }
    43 int main(){
    44   cin>>k>>m;
    45   if(m<k-1){cout<<0<<endl;return 0;}
    46   mm=getnum(k);
    47   if(k==qpow(10,mm-1)){
    48     if(m==mm){cout<<k<<endl;return 0;}
    49     else{cout<<0<<endl;return 0;}
    50   }
    51   gettable();
    52   ll tmp=1;m--;
    53   for(int i=1;i<=19;i++){
    54     if(m>cnt[i]){m-=cnt[i];ans=num[i];}
    55     else{
    56       ans=tmp+m-1;break;
    57     }
    58     tmp*=10;
    59   }
    60   cout<<ans<<endl;
    61   return 0;
    62 } 

    这个又超时有WA的,我的代码总是写得调不出来,

    Think twice,code once 啊啊啊

  • 相关阅读:
    ios手势复习值之换图片-转场动画(纯代码)
    ios地图小例子和手势的使用 供大家参考一下呦
    basicAnimation移动图形
    一个layer可以跟着画完的线移动ios程序 好玩啊。
    kvo深入浅出举例
    kvc简单实现
    block 浅析
    从相册中取图片
    绘图quartz之渐变
    绘图quartz之加水印
  • 原文地址:https://www.cnblogs.com/lcan/p/9821956.html
Copyright © 2011-2022 走看看