トピック
制限時間
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;
}