您的位置:首页 > 编程语言 > C语言/C++

CSU-ACM2017暑假集训比赛2 B - : )

2017-08-02 20:38 405 查看

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={(N−sumk−1)mod99, (N−sumk−1)mod9=0

其中,sumk−1 为前 k−1 个字符串中字符数量的和,即 (1 .. k-1) 的等差数列求和。

为知道 k−1 的值,采用二分法找到符合条件的 k−1,记为 i。

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 二分