[NOIP-P1028]吉祥数

题目描述(Description)

为了迎接圣诞,信息学兴趣小组的同学们在辅导老师的领导下,举办了一个盛大的晚会,晚会的第一项内容是做游戏:猜数。老师给每个同学发一张卡片,每张卡片上都有一个编号(此编号为非负数,且小于255),每个编号互不相同。老师制定了以下的游戏规则:第一轮,每个同学将自己编号的各位数字进行平方后再相加得到一组数,编号在这组数中出现的同学淘汰出局;第二轮,余下的同学再将自己编号的各位数字进行立方相加得到一组新数,编号在这组数中出现的同学再淘汰出局;第三轮,余下的同学再将编号的各位数字进行4次相加得到一组新数,编号在这组数中出现的同学再淘汰出局,依此类推,经过n轮后,仍留下来的同学将获得圣诞特别礼物,卡片上的数即2009年吉祥数。(假定班级人数不超过200人)

输入格式(Format Input)

第1行为1个正整数n(n<8),表示有n轮游戏
第二行是卡片上互不相同的编号,以空格隔开。

输出格式(Format Output)

输出一行,为剩下来的各个吉祥数,按从小到大顺数输出,每两个数之间有一个空格。

输入样例(Sample Input)

1
24 123 2 12 20 14 4 6 36 72

输出样例(Sample Output)

2 6 12 24 72 123

思路:

每轮相当于每位乘以(n+1)次幂,都加起来,如果不符合要求的先别急着改,因为它还可以淘汰别人。

Code

#include<bits/stdc++.h>
using namespace std;
int x,a[1001],b[1001],n;
int f(int x,int y)
{
    int ans=0;
    while(x)
    {
        ans+=pow(x%10,y);
        x/=10;
    }
    return ans;
}
int main()
{
    cin>>n;
    while(scanf("%d",&x)!=EOF)
    {
        a[x]=1;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<255;j++)
        {
            if(a[j])
            {
                int t=f(j,i+1);
                if(t<255)    b[t]=1;
            }
        }
        for(int k=0;k<255;k++)
        {
            if(a[k]&&b[k])    a[k]=0;
        }
        memset(b,0,sizeof(b));
    }
    for(int i=1;i<255;i++)
    {
        if(a[i])    cout<<i<<" ";
    }
    return 0;
 }

Join the Conversation

2 Comments

Leave a comment

Your email address will not be published. Required fields are marked *