uva10706

来源:互联网 发布:windows lua 下载 编辑:程序博客网 时间:2024/05/22 15:27

题目大意:有这样一串序列11212312341234512345612345671234567812345678912345678910123456789101112345678910…,问第i个位置数的值。

这里涉及到了二分这个蜜汁问题,那我百度了以下,贴一下二分的不同写法:
越大越好时:
while(r>l){mid=(l+r)/2…}
然后更新是不符合条件l=mid+1,否则是r=mid
越小越好时:
while(r>l){mid=(l+r+1)/2…}
然后更新是符合条件l=mid,否则是r=mid-1

代碼:

#include<cstdio>#include<cmath>#include<cstring>int p;long long sum[33000];char buf[150000];char temp[10];char* join(int q) {    int c=0, t=q;    while(q) {        c++;        q/=10;    }    temp[c--]=0;    while(t) {        //拆解每一位        temp[c--]=t%10+'0';        t /= 10;    }    return temp;}int findp(long long a) {    //找到一個值,他第一次出現的位置小於或等於a    //如果小於a說明a不是一個值的第一次出現位置,會返回一個值    //這個值第一次出現的位置是接近a的,字符串的長度其實是按順序lleijia    //下去的,所以所求位置減去這個數第一次出現的位置,相當與剪掉了前面    //冗餘的部分,差值所指向的位置就是一個累加串這個位置的值    int l=0, r=32000;    int mid;    while(l<r) {        mid=(l+r+1)/2;        if(sum[mid]>=a) r=mid-1;        else l=mid;    }    return l;}int main() {    int t, k, i;    buf[0]='0';    sum[0]=0ll;    for(i=1; i<=32001; i++) {        strcat(&buf[strlen(buf)], join(i));        sum[i] = sum[i-1]+strlen(buf)-1;    }    scanf("%d", &t);    while(t--) {        scanf("%d", &k);        printf("%c\n", buf[k-sum[findp(k)]]);    }    return 0;}
0 0
原创粉丝点击