最小生成元 (Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

来源:互联网 发布:大唐网络 编辑:程序博客网 时间:2024/05/22 04:38

如果x+x的各个数字之和得到y,就是说x是y的生成元。给出n(1<=n<=100000),

求最小生成元。无解输出0.例如,n=216,121,2005时的解分别是198,0,1979.

可以利用循环的方法很简单的AC,但是效率并不高,另一种方法是一次性枚举100000内的所有正整数到数组中,最后查询数组即可,个人感觉书上代码有点难懂以下贴上个人的代码和书上代码

//个人的渣代码#include <iostream>#include <cmath>#include <stdio.h>using namespace std;int digit[20];int answer[100000];int getLength(int n){    int bit = 0;    while(n != 0)    {        n = n/10;        bit++;    }    return bit;}void getDigit(int n){    for (int i = 0; i < getLength(n); i++)    {        digit[i] = n / int(pow(10, i)) %10;    }}int generator(int n){    int sum = n;    getDigit(n);    int length = getLength(n);    for (int i = 0; i < length; i++)    {        sum += digit[i];    }    return sum;}int main(){    for (int i = 0; i < 100000; i++)    {        answer[i] = generator(i+1);    }    int n, ok = 0, res;    cin>>n;    for (int i = 0; i < 100000; i++)    {        if (n == answer[i])        {            ok = 1;            res = i+1;        }    }    if (ok == 1)    {        cout<<res<<endl;    }    else    {        cout<<0<<endl;    }    return 0;}
//书上的精炼代码#include <stdio.h>#include <string.h>const int maxn = 100000 + 5;int ans[maxn];void solve()  //离线做法{    memset(ans, 0, sizeof(ans));    for (int i = 1; i < maxn; i++)    {        int x = i, y = i;        while (x)        {            y += x % 10;            x /= 10;        }        if (ans[y] == 0 || i < ans[y])            ans[y] = i;    }}int main(){    int T, n;    solve();    scanf("%d", &T);    while (T--)    {        scanf("%d", &n);        printf("%d\n", ans[n]);    }}
0 0