• POJ 1019:Number Sequence 二分查找


    Number Sequence
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 36013   Accepted: 10409

    Description

    A single positive integer i is given. Write a program to find the digit located in the position i in the sequence of number groups S1S2...Sk. Each group Sk consists of a sequence of positive integer numbers ranging from 1 to k, written one after another. 
    For example, the first 80 digits of the sequence are as follows: 
    11212312341234512345612345671234567812345678912345678910123456789101112345678910

    Input

    The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by one line for each test case. The line for a test case contains the single integer i (1 ≤ i ≤ 2147483647)

    Output

    There should be one output line per test case containing the digit located in the position i.

    Sample Input

    2
    8
    3

    Sample Output

    2
    2

    题意是给定了一串有规律的数,问位置i的数是0~9中的哪一个。

    自己一直再跟着POJ分类的题目在做,然后很自然地就会总看小优的博客。。。但是觉得这道题没有小优说的那么夸张,多么难。

    首先计算每一个数的长度,比如11,n[11]=2。

    之后计算从1到n 这一段数的长度,比如1234567891011,所以c[11]=13。

    最后计算总体的长度,比如1121231234123451234561234567123456781234567891234567891012345678910111,即s[11]=70

    初始化这些结束之后,剩下的就是不断切分,先二分找s数组,之后定位到哪一段,即是c数组的事情,在之后定位到是哪一个数,是n数组的事情,再然后就是这个数的第几位,手动算吧。这样逐级下来,就能得到第几个数是什么。

    主要就是做的时候思路清晰,别乱就好。

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstring>
    #pragma warning(disable:4996)
    using namespace std;
    
    int c[52850];
    long long s[52850];
    int n[52850];
    int num;
    
    int length(int x)
    {
    	int sum=0;
    	while (x != 0)
    	{
    		x /= 10;
    		sum++;
    	}
    	return sum;
    }
    
    void init()
    {
    	int i;
    	
    	c[0] = 0;
    	s[0] = 0;
    
    	for (i = 1; i <= 52849; i++)
    	{
    		n[i] = length(i);
    	}
    	for (i = 1; i <= 52849; i++)
    	{
    		c[i] = c[i - 1] + n[i];
    	}
    
    	for (i = 1; i <= 52849; i++)
    	{
    		s[i] = s[i - 1] + c[i];
    	}
    }
    
    
    int main()
    {
    	init();
    	
    	int Test,left,pos;
    	int i;
    	scanf("%d", &Test);
    	
    	while(Test--)
    	{
    		scanf("%d", &num);
    
    		left = lower_bound(s + 1, s + 52845, num) - (s + 1);
    		pos = num - s[left];
    
    		left= lower_bound(c + 1, c + 52845, pos) - (c + 1);
    		pos = pos - c[left];
    
    		left++;
    		pos = n[left] - pos +1;
    
    		i = 1;
    		while (i < pos)
    		{
    			left /= 10;
    			i++;
    		}
    		cout << left % 10<<endl;
    	}
    
    	return 0;
    }
    



    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Android微信九宫格图片展示控件
    ImageView设置rounded corner
    Android TitleBar推荐
    《Windows核心编程》目录索引
    《Windows内核分析》专题-索引目录
    wchar,char,string,wstring互转
    键盘过滤
    串口过滤
    Vmware中Linux 虚拟机与Windows物理机建立共享文件夹
    遍历某一进程模块
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4899601.html
Copyright © 2020-2023  润新知