吉祥数(NDK1044)

吉祥数

Time Limit:1000MS  Memory Limit:65536K
Total Submit:42 Accepted:10 

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

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

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

Sample Input 
1
24 123 2 12 20 14 4 6 36 72

Sample Output 
2 6 12 24 72 123

Source 
NOIdaokan

算法:模拟

一开始对这个题有点大意了,各种错误各种WA,后来改了半天还是不对,突然发现题意理解错了,编号数一定小于255,因此不存在编号达80+W的数,这个一开始就错了……

把每个同学的编号标记为1,已经淘汰的标记为0,要在下一轮中淘汰的标记成-1(这里我也理解错了,我以为是从前往后的可能再本轮中就被淘汰了……)

program NDK1044;

const
 maxn=200;
 maxx=255;

var
 n,tot,cifang:longint;
 b:array [0..maxx] of longint;

procedure init;
var
 x:longint;
begin
 fillchar(b,sizeof(b),0);
 readln(n);
 while not eoln do
  begin
   read(x);
   b[x]:=1;
  end;
end;

function change(x:longint):longint;
var
 i,j,ans,t,xx:longint;
 s:string;
begin
 str(x,s);
 ans:=0;
 for i:=1 to length(s) do
  begin
   t:=ord(s[i])-48;
   xx:=t;
   for j:=1 to cifang do t:=t*xx;
   inc(ans,t);
   if ans>255 then exit(-1);{累计求和,大于255表示这个状态在下一轮中不可能,这个状态实际上不成立。}
  end;
 exit(ans);
end;

procedure main;
var
 i,j,p:longint;
begin
 for i:=1 to n do
  begin
   cifang:=i;
   for j:=0 to 255 do
    begin
     if (b[j]=1) or (b[j]=-1) then{还没有被淘汰的和下一轮即将淘汰的都可以继续计算。}
      begin
       p:=change(j);
       if b[p]=1 then b[p]:=-1;
      end;
    end;
   for j:=0 to 255 do if b[j]=-1 then b[j]:=0;{0表示确实被淘汰了,在下一局中不会出现。}
  end;
end;

procedure outit;
var
 i:longint;
begin
 for i:=0 to 255 do if b[i]=1 then write(i,' ');{从前往后寻找。}
end;

begin
 assign(input,'NDK1044.in'); reset(input);
 assign(output,'NDK1044.out'); rewrite(output);

 init;
 main;
 outit;

 close(input); close(output);
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值