poj 1019 Number Sequence 【组合数学+数字x的位宽函数】

题目地址:http://poj.org/problem?id=1019

Number Sequence

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 35680   Accepted: 10287

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分析:序列如上所示,要求这个序列的第n位是什么,首先需要知道的是:一个数x的宽度怎么算?可以每次让x除10,看看多少次可以除尽。不过比较麻烦,有简单的算法:f[x]=log10(x)+1;  999的位宽=log10(999)+1=3;有了这个就可以来想怎么解决上面的问题。参考博客1:http://www.cnblogs.com/ACShiryu/archive/2011/08/05/2129009.html参考博客2:http://blog.csdn.net/lyy289065406/article/details/6648504一个大序列可以划分成许多个有规律的子序列,先找到第n位在那个子序列上,再找到在子序列的那个数字上,再找到在该数字的哪一位上。代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <cmath>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#define N 100000+100

using namespace std;
long long int f[40000];
long long int s[40000];
int main()
{
    int i, j;

    memset(f, 0, sizeof(f));
    memset(s, 0, sizeof(s));

    long long int sum=0;
    f[1]=1; s[1]=1;
    i=2;
    while( i<=31269 )
    {
        f[i]=f[i-1]+(int)log10((double)i)+1;
        s[i]=s[i-1]+f[i];
        i++;
    }//打表

    int tg; scanf("%d", &tg);
    while(tg--){
        int n;
        scanf("%d", &n);
        for(i=1; i<=31269; i++){
            if(s[i]>=n) break;
        }
        int pos=i; //找到在第pos个子序列上
        n=n-s[pos-1];
        for(j=1; j<=pos; j++){
            n=n-((int)log10((double)j)+1); //减去当前这个数的宽度
            if(n<=0){
                break;
            }
        }
        int pos2=j;//找到在子序列的第pos2个数上
        n=n+(int)log10((double)pos2)+1;//在这个数的第n位上

        int dd=(int)log10((double)pos2)+1-n;
        int q=1, w=1;
        for(i=1; i<=dd; i++) {q=q*10; w=w*10;} w=w*10;

        int ans;
        ans=pos2%w/q;
        printf("%d\n", ans );//输出结果
    }
    return 0;
}
				
时间: 2024-10-08 01:45:05

poj 1019 Number Sequence 【组合数学+数字x的位宽函数】的相关文章

poj 1019 Number Sequence (组合数学)

链接:poj 1019 题意:有一个由数字组成的序列规律为 112123123412345123456123456712345678123456789123456789101234567891011 ... 输入位置n,计算这一串数字第n位是什么数字 分析:模拟分组,把1看做第1组,12看做第2组,123看做第3组... 那么第i组就是存放数字序列为 [1,i]的正整数,但第i组的长度不一定是i, 已知输入查找第n个位的n的范围为(1 ≤ n ≤ 2147483647), 那么至少要有31268

POJ 1019 Number Sequence 题解

这又是一道看似简单,实际挺困难的题目. 本来想做道基础题消遣一下的,没想到反被消遣了-_-|||. 看个人的基础吧,对于数学好的会简单点,但是由于情况太多,需要都考虑全,故此难度应该在4星以上了. 我这里使用的方法就是直接打表,然后直接模拟,利用打表去掉一大段数据,剩下数据量十分小了,故此可以直接模拟. 打表是为了计算前面的周期数,把周期数直接去掉. 主要难点是后面10位数以上的数有2位, 3位,4位等情况要考虑.- 下面使用getNewNums一个函数解决了,想通了,就几行代码,还不用难理解的

poj 1019 Number Sequence 二分

Number Sequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 34391   Accepted: 9879 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...

POJ 1019 Number Sequence (循环递增序列的的第K个值)

Number Sequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35823   Accepted: 10340 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..

poj 1019 Number Sequence (数学)

链接:http://poj.org/problem?id=1019 分析:就是计数的问题..可以先算出112123...m共有多少位,具体式子看代码..然后二分取一个最大的小于n的m,接下来考虑123...m有多少位,再二分一下求解就可以了..具体式子还是看代码.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long

POJ 1019 Number Sequence

题意:问有如下规律的数列的第n项是啥: 11212312341234512345612345671234567812345678912345678910123456789101112345678910 解法:每段连续数字为一组,算每组序列的长度,累加直到超过n,说明n在前一组连续数字内,枚举组内数字,累加长度直到超过n,说明n在前一数字中,找出这一数位输出. 总的来说就是一有点恶心的模拟……最后我想说…… 注意longlong 对……每次都记不住……_(:з」∠)_ 代码: #include<s

poj 2478 Farey Sequence(基于素数筛法求欧拉函数)

http://poj.org/problem?id=2478 求欧拉函数的模板. 初涉欧拉函数,先学一学它基本的性质. 1.欧拉函数是求小于n且和n互质(包括1)的正整数的个数.记为φ(n). 2.欧拉定理:若a与n互质,那么有a^φ(n) ≡ 1(mod n),经常用于求幂的模. 3.若p是一个质数,那么φ(p) = p-1,注意φ(1) = 1. 4.欧拉函数是积性函数: 若m与n互质,那么φ(nm) = φ(n) * φ(m). 若n = p^k且p为质数,那么φ(n) = p^k - p

PKU 1019 Number Sequence(模拟,思维)

题目 以下思路参考自discuss:http://poj.org/showmessage?message_id=176353 /*我的思路: 1.将长串数分成一个个部分,每个部分是从1到x的无重复的数字序列 2.每个序列比前一个序列多的位数是他的最后一个数的位数,如12345678910比123456789多最后一个10, 即多占了两位,由此可推算出任何一个序列的长度 3.输入位置n,则从1到n查找,每次位置移动一个序列的长度,如果第j个加上序列长度超过n,则输出j这个整数的从个位数第j-n+1

Number Sequence POJ 1019

给定一个字符串满足规律 11212312345--,求其第k位的数字. 算法思路: 分组来看,第一组1 第二组12 第三组123 第K组[1:k] 1-9组每组1位, 10-99组每组2位 依次类推. 网上大部分解法,用一个数组表示到第k组时,一共需要多少位数,但这个方法需要额外的空间,而且空间大小并不是非常容易确定. 伪代码的思路:sum 表示 while true last-sum = sum; group-size = last-group-size + member-size; // 本