• poj1019 Number Sequence


    在自己看来,思路虽然没错,但总是出现这样那样的细节问题。。。。

    题目描述:http://poj.org/problem?id=1019

    解题思路:开始是以为第i个数字,结果错了。原来是第i位。。。题目前80位

    11212312341234512345612345671234567812345678912345678910123456789101112345678910

    寻找第i位的数字分为四个步骤

    1,找大块:大块是112......123456789,112123...100;也就是判断第i位所在序列的最大的数字多少位数字

    2,找小块:找到第i位所在的序列,1234..i..,比如第8位在11234这个序列中,第11位在12345这个序列中

    3,找数字:找到第i位所在的数字

    4,找位:在数字中找到位

    代码AC memory:416k  time:0ms

    代码未优化 第一次写blog。。。

    #include <stdio.h>
    #include
    <stdlib.h>
    #include
    <math.h>
    //本程序中k是题目中的i
    unsigned int cs,sz;
    int a[]={0,1,11,192,2893,2889+9000*4+5};
    unsigned
    int erfen(int wei,unsigned int z)//用二分查找法找到i所在的小块序列
    {
    unsigned
    int num=(int)pow(10,wei-1),low,high,mid,temp,temp1,temp2;
    low
    =num;
    high
    =num*10-1;
    while(low<=high)
    {
    mid
    =(low+high)/2;
    temp1
    =(mid-num+1-1)*a[wei]+(mid-num+1-1)*(mid-num+1-2)/2*wei;
    temp
    =(mid-num+1)*a[wei]+(mid-num+1)*(mid-num)/2*wei;
    if(temp1<z&&z<=temp)//从找大块取得的位数最小数计算,到i的位数总数z大于前面的序列和,小于等于当前序列和
    {
    break;
    }
    else if(z>temp)
    {
    low
    =mid+1;
    }
    else
    {
    high
    =mid-1;
    }
    }
    sz
    =z-((mid-num)*a[wei]+(mid-num)*(mid-num-1)/2*wei);//取得i在序列中的位置
    return mid;

    }
    int wei(int k)//找大块,就是看i所在序列最大数是几位数,返回位数
    {
    if(k>189414495)
    {
    cs
    =189414495;
    return 5;
    }
    else if(k>1395495)
    {
    cs
    =1395495;
    return 4;

    }
    else if(k>9045)
    {
    cs
    =9045;
    return 3;

    }
    else if(k>45)
    {
    cs
    =45;
    return 2;

    }
    else
    {
    cs
    =0;
    return 1;

    }
    }
    int main(int argc, char** argv) {

    unsigned
    int k,z;
    int n,d,i,num,no,i1;
    scanf(
    "%d",&n);
    while(n--)
    {
    scanf(
    "%d",&k);

    d
    =wei(k);
    z
    =k-cs;
    num
    =erfen(d,z);
    i
    =d;
    while(1)//查找i所在数字的位数
    {
    if(sz<=(a[i]-i))
    i
    --;
    else
    {
    break;
    }
    }

    sz
    =sz-a[i]+i;
    no
    =(sz-1)/i;
    sz
    =sz-no*i;
    no
    =(int)pow(10,i-1)+no;//找数字
    printf("%d\n",no/(int)pow(10,i-sz)%10);//取位



    }
    return (EXIT_SUCCESS);
    }

     



  • 相关阅读:
    C语言版本:单链表的实现(优化版本)
    C语言版本:单链表的实现
    C语言版本:顺序表的实现
    C++:多态浅析
    C++:同名隐藏和赋值兼容规则
    C++:钻石继承与虚继承
    C++:派生类的构造函数和析构函数的调用顺序
    Docker安装和使用
    Node10.15.0的安装
    碎碎叨叨
  • 原文地址:https://www.cnblogs.com/fengyuehan/p/poj1019.html
Copyright © 2020-2023  润新知