POJ 1019

来源:互联网 发布:阿里的数娱媒体矩阵 编辑:程序博客网 时间:2024/06/06 02:38

题目链接: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;}



原创粉丝点击