思路:
不知道为什么我的搜索专题出现了这道题......好像是可以折半搜索,但感觉复杂度很高,观察了一下:
第一个数:1位
第二个数:2位
......
第n个数:n位
那如果连起来,连接完第n个数,这个数的位数为:
1 + 2 + 3 + 4 ......+n
这不正是等差数列求和吗?
然后我用下面的代码简单测了一下。
#include <bits/stdc++.h>
using namespace std;
int main(){
long long ans = 1;
int i;
for(i=1 ;i<=31 ;i++){
ans *= 2;
}
cout << ans << endl;
long long k = 1;
while(k*(k+1)/2 <= ans){
k++;
}
printf("k = %d\n",k);
return 0;
}
我先开一个65000左右大小的数组,预处理a[i] = i*(i+1)/2。对于每一个给定的位数k放进a数组里面二分搜索,找到下限pos,用k-(pos)*(pos+1)/2,剩下的就是从1开始的属于最后一个数的一个数串,然后对9取余即可,若取余为0,则说明刚好剩下9个数(或9的倍数),那么输出9,否则直接输出即可。
1A代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 65550;
long long a[maxn];
void init(void){
long long i;
a[0] = 0;
for(i=1 ;i<maxn ;i++){
a[i] = i*(i+1)/2;
}
}
int main(){
init();
int k;
scanf("%d",&k);
while(k--){
long long n,pos;
scanf("%lld",&n);
pos = lower_bound(a,a+maxn,n) - a;
while(pos*(pos+1)/2 >= n){
pos--;
}
long long ans = n - (pos*(pos+1)/2);
ans %= 9;
if(ans == 0){
printf("9\n");
}
else{
printf("%d\n",ans);
}
}
return 0;
}