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 啊啊啊

  • 相关阅读:
    Apache 虚拟主机 VirtualHost 配置
    EAX、ECX、EDX、EBX寄存器的作用
    Python中文文档 目录(转载)
    八度
    POJ 3268 Silver Cow Party (最短路)
    POJ 2253 Frogger (求每条路径中最大值的最小值,Dijkstra变形)
    2013金山西山居创意游戏程序挑战赛——复赛(1) HDU 4557 非诚勿扰 HDU 4558 剑侠情缘 HDU 4559 涂色游戏 HDU 4560 我是歌手
    HDU 4549 M斐波那契数列(矩阵快速幂+欧拉定理)
    UVA 11624 Fire! (简单图论基础)
    HDU 3534 Tree (树形DP)
  • 原文地址:https://www.cnblogs.com/lcan/p/9821956.html
Copyright © 2011-2022 走看看