B - : )
假设:
S1 = 1
S2 = 12
S3 = 123
S4 = 1234
.........
S9 = 123456789
S10 = 1234567891
S11 = 12345678912
............
S18 = 123456789123456789
..................
现在我们把所有的串连接起来
S = 1121231234.......123456789123456789112345678912.........
那么你能告诉我在S串中的第N个数字是多少吗?
Input
输入首先是一个数字K,代表有K次询问。
接下来的K行每行有一个整数N(1 <= N < 2^31)。
Output
对于每个N,输出S中第N个对应的数字.
Sample Input
6
1
2
3
4
5
10
Sample Output
1
1
2
1
2
4
观察发现,如果设第 N 个数字位于第
k
个字符串内,那么记第 N 个数字为
n={(N−sumk−1)mod99, (N−sumk−1)mod9=0
其中, sumk−1 为前 k−1 个字符串中字符数量的和,即 (1 .. k-1) 的等差数列求和。
为知道 k−1 的值,采用二分法找到符合条件的 k−1 ,记为 i <script type="math/tex" id="MathJax-Element-730">i</script>。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
long long Find(long long n){
long long left = 0, right = (1<<16), mid, ans, sum;
while(left <= right){
mid = (left + right) / 2;
sum = (1+mid)*mid/2;
if(sum < n){//mid is too small or just it.
ans = mid;
left = mid + 1;
}
else//mid is too large.
right = mid - 1;
}
return ans;
}
int main(){
#ifdef TEST
freopen("test.txt", "r", stdin);
#endif // TEST
long long k, n, res, i;
cin >> k;
while(k--){
cin >> n;
i = Find(n);
res = (n-(1+i)*i/2)%9;
if(res == 0)
cout << 9 << endl;
else
cout << res << endl;
}
return 0;
}