题目链接:http://poj.org/problem?id=1019
————————————————————————————————————————
题目思路:
觉得这不算是一个dp题,只是需要提前打表,用了一点递归的方法。
学了两个新的函数。嗯。细节部分要注意。
另外,如果能像其他人的题解中,把问题按照公式解决,那么细节问题就不需要考虑的太多,出错率也会降低。
————————————————————————————————————————
题目细节:
1、double log10(double x); 表示以10为底的对数值。
2、double pow( double x, double y ); 计算x的y次幂。
3、网上找的题解,用简单公式解决问题。
————————————————————————————————————————
我的代码:
#include <iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
int len[40000];
long long int sta[40000];
int _log[7];
int main()
{
//freopen("in.in", "r", stdin);
//freopen("out.txt","w",stdout);
int t = 0,i = 0,n = 0,j = 0,temp = 0;
long long int sum = 0;
len[0] = 0;
i = 1;
sta[0] = 0;
while(1)
{
len[i] = len[i-1] + (unsigned int)log10((double)i)+1; //注意本处的技巧
sta[i] = sta[i-1]+len[i];
sum += len[i];
i++;
if(sum>= 2147483647)
break;
}
n = i;
_log[1] = 10;
for(i = 2;i<=5;i++)
_log[i] = 10*_log[i-1];
_log[0] = 1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&i);
for(j = 0;j<n;j++)
if(i<=sta[j])
break;
i = i-sta[j-1];
for(j = 1;j<=4;j++) //这里一开始的4处写的是5,故大数部分的答案是错误的。
{
if(i<=len[_log[j]-1])
break;
}
i = i-len[_log[j-1]-1];
temp = i%j;
i = i/j;
if(temp == 0)
{
i = _log[j-1]+i-1;
temp = 1;
}
else
{
i = _log[j-1]+i;
temp = j+1-temp;
}
while(temp--)
{
j = i%10;
i = i/10;
}
printf("%d\n",j);
}
return 0;
}
网上的代码:#include <iostream>
#include <cmath>
using namespace std;
unsigned int a[31270], s[31270];
/* 打表 */
void reset()
{
int i;
a[1] = 1;
s[1] = 1;
for(i = 2; i < 31270; i++)
{
/* 每一组数字都比上一组长 (int)log10((double)i) + 1 */
a[i] = a[i-1] + (int)log10((double)i) + 1;
s[i] = s[i-1] + a[i];
}
}
/* 计算 */
int work(int n)
{
int i = 1;
int length = 0;
/* 找到 n 所在的组 */
while (s[i] < n) i++;
/* n 在该组的下标 */
int pos = n - s[i-1];
/* length: n指向的数字的最后一位的下标 */
for (i = 1; length < pos; i++)
{
length += (int)log10((double)i) + 1;
}
/* 去掉所求位后面的数字然后取余 */
/* i: n指向的数字 + 1 */
return ((i-1) / (int)pow((double)10, length - pos)) % 10;
}
int main()
{
int t;
unsigned int n;
reset();
cin >> t;
while(t--)
{
cin >> n;
cout << work(n) << endl;
}
//system("pause");
return 0;
}