标签:二分
二分水题 放组合数学里。。。可能有什么正规姿势吧Orz
112123123412345...这种串 分成长度1 2 3 4 5...的串 注意有多位数
把长度累加到一个数组里 注意要累加 因为查询的时候查的是原串中对应位置的数 因此要累加上前一次的长度 然后二分处该串前的总长 用查询的位置-之前串的总长 就是在最长的串中的位置 因此还要打个最长串的表
这些我都写一个循环里了 看着有点乱 可以拆开写。。。
代码如下:
#include <iostream> #include <cstdio> #include <cstdlib> #define ll long long #define INF 2147483648 using namespace std; //2147483647 ll r[33333]; //二分查的数组 char str[233333]; //最长串的表 int tp,len; //累计二分数组长度 和最长串长度 void Init() { int i,j,cnt,pw,k,s; r[0] = 0; len = 1; //最长串从1开始 便于查询 for(tp = 1, i = 1, j = 1, cnt = 1, pw = 10; r[tp-1] <= 2147483647; i += cnt, tp++) //i累计当前串长 cnt累计最后一个数长度 j累计最后一个数(多位数) pw最后一个数位(1 10 100 100...) { r[tp] = r[tp-1] + i; k = j; s = pw/10; while(s) { str[len++] = k/s + '0'; k%=s; s /= 10; } ++j; if(j/pw) { pw *= 10; cnt++; } } tp--; r[tp] = INF; } int main() { int l,rr,ans,t,mid; ll pos; Init(); scanf("%d",&t); while(t--) { scanf("%lld",&pos); l = ans = 0, rr = tp; while(l <= rr) //二分查找 { mid = l+rr>>1; if(r[mid] < pos) { ans = mid;//小于查询位置的数中最大的 注意不可等 l = mid+1; }else rr = mid-1; } printf("%c\n",str[pos-r[ans]]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:二分
原文地址:http://blog.csdn.net/challengerrumble/article/details/47781475