顺便说一句,我现在是按照百度百科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值

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

667

被折叠的 条评论
为什么被折叠?



