T4カッコウイーストの素晴らしいシーケンス

トピック

制限時間

1秒

スペースの制約

64MB

タイトル説明

ググドンはひどい複雑な機能に取り組んでいますが、Aプラスをしっかりと持っているググドンにとって、彼女は長い間授業に出席することをやめました。

このとき、彼女は突然、睡眠中の奇妙な無限のシーケンスについて考えました:112123123412345 ...

このシーケンスは、連続する正の整数で構成されるいくつかの部分で構成されます。最初の部分には1〜1のすべての数字が含まれ、2番目の部分には1〜2のすべての数字が含まれ、3番目の部分には1〜3のすべての数字が含まれます。 、i番目の部分には、常に1からiまでのすべての数値が含まれます。

したがって、このシーケンスの最初の56項目は11212312341234512345612345671234567812345678912345678910になります。ここで、最初の項目は1、3番目の項目は2、20番目の項目は5、38番目の項目は2、56番目の項目は0です。

Gu Gu Dongは、k番目の番号を知りたがっています。しかし、目が覚めた後、先生の言ったことは理解できなくなったので、彼女はこの仕事をあなたに任せました。

入力フォーマット

入力は複数の行で構成されます。

最初の行の整数qは、クエリのグループがq個あることを示します(1 <= q <= 500)

次のi + 1行目は、i番目の入力kiを意味し、ki番目の番号を要求することを意味します。(1 <= ki <= 1018)

出力フォーマット

出力にはq行が含まれます

i番目の行はクエリkiの出力結果を出力します。

サンプル入力

5
1
3
20
38
56

サンプル出力

1
2
5
2
0

データポイント

ここに写真の説明を挿入

練習

1. Sum [x]は、シーケンス内でxが最初に現れる位置を表し、a [x]は1からxまでの桁数を表します。
2.入力位置kごとに、二分法を使用して、sum [mid]> = kの最初のmidを見つけます。midは、kが配置されている先行要素の合計です。
3. k = k-weizhi(mid-1,0)とし、a [mid]> kがkである数である最初のmidを見つけます。
4. k = k-weizhi(mid-1,1)とします。kはそれが配置されている一連の番号であり、番号midを文字列に変換し、k番目の桁が目的の出力番号になるようにします。
5.位置を見つける関数では、sumは、解決する上位レベルのシーケンス長としてaを必要とするため、sumsumとaが結合されます。
6.最初に、xがこのオーダーの大きさの場合、powのオーダーの合計とaを見つけ続け、次にこのオーダーの最小値からxまでの合計とaを見つけます

エラー

1.両方の検索で、返される結果を> kにする最初の値が見つかるため、weizhi(mid、0/1)> = kの場合、r +ではなくmid = r-1であることに注意してください。 1
2.最初に、前の項とすべての計算を配列に格納することを検討しましたが、REエラーが発生することがわかりました。配列は範囲外である必要があると考えてください。データ範囲は1e18であるため、大きな配列に格納されているとは見なされません。 (しかし、それは桁単位で増加する配列に格納できるように感じます)。
3.to_stringはc ++ 11でサポートされていますが、下位バージョンではサポートされていません

コード

#include<iostream>
#include<string>
#include<cmath>
#include<cstdio>
using namespace std;
long long weizhi(long long x,int ch)
{
    
    
 long long pow=1,sum=0,a=0,n=0,weishu=0;
 while(true)
 {
    
    
  pow=pow*10;
  weishu=weishu+1;
  if(x>pow-1)
  {
    
    
   n=pow-pow/10;
   sum=sum+a*n+(n+1)*n/2*weishu;
   a=a+n*weishu;
  }
  else
  {
    
    
   n=x-pow/10+1;
   sum=sum+a*n+(n+1)*n/2*weishu;
   a=a+n*weishu;
   break;
  }
 }
 if(ch==0)
  return sum;
 else
  return a;
}
int main()
{
    
    
 long long ans,k;
 long long q,l,r,mid;
 cin>>q;
 for(int i=0;i<q;i++)
 {
    
    
  cin>>k;
  l=0;r=1e9;
  while(l<=r)
  {
    
    
   mid=(l+r)>>1;
   if(weizhi(mid,0)>=k)
   {
    
    
    ans=mid;
    r=mid-1;
   }
   else
    l=mid+1;
  }
  k=k-weizhi(ans-1,0);
  l=0;
  r=ans+1;
  while(l<=r)
  {
    
    
   mid=(l+r)>>1;
   if(weizhi(mid,1)>=k)
   {
    
    
    
    ans=mid;
    r=mid-1;
   }
   else
    l=mid+1;
  }
  k=k-weizhi(ans-1,1);
  string s =to_string(ans);
  printf("%d\n",s[k-1]-'0');  
  } 
 return 0;
 } 

おすすめ

転載: blog.csdn.net/alicemh/article/details/105389027