POJ 1019 Number Sequence

本文详细解析了POJ1019 Number Sequence题目的解题思路,介绍了作者从初略想法到最终高效解决方案的过程,并附带完整的C++代码实现。

POJ 1019 Number Sequence


顺便说一句,我现在是按照百度百科Poj里面经典题目来刷的....但发现其实挺简单的(当然还是要经过百度大神和Discuss的思路启发啥的)......QAQ你们这群编词条的坏人骗我!!!

我做题的顺序大概是晚上读题,睡觉前整理思路催眠入睡;早晨起来看别人的思路再对比自己的思路,修改整理自己的思路,编程,测试;晚上入睡前写当天的解题报告=v=


算法解析:

刚开始我的思路:

1)求出k对于1-99 10-999 100-999 1000-9999 还是10000以上的分类中对于S1....Sk数字链位数长度的数学解析式(其实蛮好求的,就是几个等差数列)

2)第一步:先对输入的数字i作分类判断,看看它是在1-99 10-999 100-999 1000-9999 还是10000以上的群组;第二步,利用半分法确定输入的数字位数是在哪一个群组Sk中

3)求出输入数字位数是在群组Sk的哪一个数字c上

4)求出输入数字位数是在数字c的哪一个位数上

后来对比别人的思路发现可以使用空间存储每个群组Sk的位数(实际是利用空间使得算法的复杂度降低)因为我实在不想笔算求数学解析式(实际上就是懒),因此采用了后一种思路(反正最后时间都是0MS)虽然我觉得我的初始思路可能时间消耗会更少,另外初始思路需要使用long型,而后来的则使用int就够了...


算法实现:没啥困难的,理解了思路只要注意几个变量加加减减的顺序就好了~


#include<iostream>
#include<cstdio>
#include<string>
using namespace std;

int bit[31300];

int main()
{
	//预处理,将前31300个组每组数字的位数存储在数组中
	int c=1,w=1;
	for (int i=1; i!=31300; i++)
	{
		bit[i]=c;
		if (i==9 || i==99 || i==999 || i==9999)
		{
			w++;
		}
		c+=w;
	}
	//输入
	int t;
	cin>>t;
	for (int i=0; i!=t; i++)
	{
		int n;
		cin>>n;
		//首先寻找在哪一组
		int j=1;
		while (n-bit[j]>0)
		{
			n-=bit[j];
			j++;
		}
		//在第j组后然后寻找是哪一个数
		int c=1,w=1;
		while (n-w>0)
		{
			n-=w;
			if (c==9 || c==99 || c==999 || c==9999)
			{
				w++;
			}
			c++;
		}
		//该数字为c后最后输出是这个数的哪一个数字
		char t[16];
		sprintf(t,"%d",c);
		cout<<t[n-1]<<endl;
	}
	return 0;
}

参考资料:

参考了一下poj上discuss中不使用long型的代码(其实就是默写了一遍吧混蛋...)

另外用了一下别人算出来的最大群组Sk值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值