https://vjudge.net/contest/367072#problem/C
套娃题qwq
第k个位置它肯定会在一个区间里,[1234567891011][123456789101112],这样是两个区间
先确定第k位所在区间的最大的数是几位数,比如这个区间[123456789101112]就是两位数;
假设是3位数,那么它就会有900个区间,
再确定答案区间在这个900个区间里是第几个,
随之你就确定了这个区间和目标位置在区间里是第几位;
然后再确定目标位置在这个区间里是占的是几位数
比如这个区间][123456789101112],它占了最后一位,那也就是12,两位数;
比如1000,1001,(1)002
然后你再确定它在这些四位数里是第几个
目标位置是括号那里,那么它在这些四位数里是第3个
随之你就能确定它在这个数里是第几位
然后就可以过题啦!
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 10000 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) using namespace std; long long T,l,r,k,t,mid,L,R,cnt; long long a[N],b[N],c[N],d[N]; void in(long long &x){ long long y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(long long x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } bool check(long long x){ long long l=b[t-1]+t,r=l+(x-1)*t; return ((l+r)*x/2)<k; } long long sum(long long x){ long long l=b[t-1]+t,r=l+(x-1)*t; return (l+r)*x/2; } void deal(long long x){ if(x>9) deal(x/10); d[++cnt]=x%10; } signed main(){ c[1]=1; For(i,2,9) c[i]=c[i-1]*10; k=9; For(i,1,9){ l=r+i;r=(k-1)*i+l; a[i]=a[i-1]+(l+r)*k/2; k*=10; } k=9; For(i,1,9){ b[i]=b[i-1]+k*i; k*=10; } in(T); while(T--){ in(k); For(i,1,9){ if(a[i]>=k){ t=i; break; } } k-=a[t-1]; l=1;r=1e9; while(l<r){ mid=(l+r)>>1; if(check(mid)) l=mid+1; else r=mid; } k-=sum(l-1); For(i,1,9){ if(b[i]>=k){ t=i; break; } } k-=b[t-1]; L=k/t; R=k%t; if(R==0){ long long temp=c[t]+L-1; o(temp%10);p(' '); } else{ cnt=0; long long temp=c[t]+L; deal(temp); o(d[R]);p(' '); } } return 0; }