POJ 1019 数论基础题

Number Sequence
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 37350 Accepted: 10780

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

Source

Tehran 2002, First Iran Nationwide Internet Programming Contest

[Submit]   [Go Back]   [Status]   [Discuss]

题意:给你一个这样的数列1,12,123,1234,1234,12345,....要你求出第n位的数字是什么。

思路:一开始把两位数以上的数当成只有一位数来算,然后就WA了;sum[i]表示以i结尾到前面所以数的总位数;比如sum[3]=6;(即1,12,123的位数总和);

代码:

#include<cstdio>  
#include<cstring>
#include <algorithm>
#include <cmath>
using namespace std;  
#define maxn 100007
#define inf 0x3f3f3f3f
typedef long long ll;
ll sum[40007],n;
void fun()
{
	sum[0] = 0;
	for(int i = 1;i<40000;i++){
		if(i <10){
			sum[i] = sum[i-1] + i;
		}
		else if(i >= 10 && i <100){
			sum[i] = sum[i-1] + 9+(i-9)*2;
		}
		else if(i >= 100 && i <1000){
			sum[i] = sum[i-1] + 9 + (99-9)*2 + (i-99)*3;
		}
		else if(i >= 1000 && i<10000){
			sum[i] = sum[i-1] + 9 + (99-9)*2 + (999-99)*3 + (i-999)*4;
		}
		else if(i >= 10000 && i < 100000){
			sum[i] = sum[i-1] + 9 + (99-9)*2 + (999-99)*3 + (9999-999)*4 + (i-9999)*5;
		}
	}
}
int main()  
{  
#ifdef CDZSC_June
	freopen("t.txt", "r", stdin);  
	//freopen("E:\\w.txt", "w", stdout); 
#endif  
	int t,p,k;
	scanf("%d",&t);
	fun();
	while(t--)
	{
		scanf("%lld",&n);
		for(int i = 1; ;i++)
		{
			if(sum[i] > n){
				p = i;
				break;
			}
		}
		if(n-sum[p-1] == 0){
			printf("%d\n",(p-1)%10);
		}
		else{
			ll p1;
			if(n-sum[p-1] < 10){
				printf("%lld\n",n-sum[p-1]);
			}
			else if(n-sum[p-1] >= 10 && n-sum[p-1] <190){
				p1 = n-sum[p-1] - 9;
				k = (p1-1)/2;
				if(p1%2==0){
					printf("%d\n",(10+k)%10);
				}
				else{
					printf("%d\n",(10+k)/10);
				}
			}
			else if(n-sum[p-1] >= 190 && n-sum[p-1] <2890){
				p1 = n-sum[p-1] - 9 - 90*2;
				k = (p1-1)/3;
				if(p1%3==0){
					printf("%d\n",(100+k)%10);
				}
				else if(p1%3==1){
					printf("%d\n",(100+k)/100);
				}
				else{
					printf("%d\n",((100+k)/10)%10);
				}
			}
			else if(n-sum[p-1] >= 2890 && n-sum[p-1] <38890){
				p1 = n-sum[p-1] - 9 - 90*2 - 900*3;
				k = (p1-1)/4;
				if(p1%4==0){
					printf("%d\n",(1000+k)%10);
				}
				else if(p1%4==1){
					printf("%d\n",(1000+k)/1000);
				}
				else if(p1%4==2){
					printf("%d\n",((1000+k)/100)%10);
				}
				else{
					printf("%d\n",((1000+k)/10)%10);
				}
			}
			else if(n-sum[p-1] >= 38890 && n-sum[p-1] <488890){
				p1 = n-sum[p-1] - 9 - 90*2 - 900*3 - 9000*4;
				k = (p1-1)/5;
				if(p1%5==0){
					printf("%d\n",(10000+k)%10);
				}
				else if(p1%5==1){
					printf("%d\n",(10000+k)/10000);
				}
				else if(p1%5==2){
					printf("%d\n",((10000+k)/1000)%10);
				}
				else if(p1%5==3){
					printf("%d\n",((10000+k)/100)%10);
				}
				else{
					printf("%d\n",((10000+k)/10)%10);
				}
			}
		}
	}
	return 0;  
}  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值