HRBUST 1547 模拟链表

来源:互联网 发布:淘宝联盟登录淘宝名 编辑:程序博客网 时间:2024/06/04 20:00
1997-1998 年欧洲西南亚洲区预赛之后,举办了一场隆重的聚会。主办方发明了一个特殊的方式去挑选那些自愿去洗脏碟子的参赛选手。先让那些选手一个挨着一个的排成一条队。 每个选手都获得一个编号,那些编号是从2开始的,第一个的编号是2 ,第二个人的编号是3,第三个人的编号是4,以此类推。

第一个选手将被问到他的编号(编号为2)。他将不用去清洗了,直接参加聚会,但是他身后的所站的位置是2的倍数的人必须去厨房(那些人的编号分别为4, 6, 8 等等)。然后在那队伍中的下一个选手必须报数。他回答3,他可以离开去参加聚会,但是在他身后的每个是三的倍数的选手将会被选上(那些人的编号分别为9,15,21等等)。下一个被选上的人的编号是5,并且将可以离开去参加聚会,但是在他身后并且站的位置是5的倍数的人将会被选上去清洗碟子(那些人的编号分别为19,35,49等等).下一个被选上的人的编号是7,并且将可以离开去参加聚会,但是在他身后并且站的位置是7的倍数的人将会被选上去清洗碟子,以此类推。

让我们称那些没有被选上去洗碟子的那些选手的编号为幸运数字。继续这个挑选的方式,那些幸运的数字是2, 3, 5, 7, 11 , 13, 17等等的递增序列。 为下一次的聚会寻找幸运数字!

Input
本题有多组测试数据,每组测试数据包含一个整数n,1<=n<=3000。

Output
对于每组测试数据输出一个数字,代表对应的幸运号码。

Sample Input
1
2
10
20

Sample Output
2
3
29
83

分析,每次有人去厨房或者参加了聚会的话,后面的人所站位置的编号会改变,通过模拟链表并设一个计数变量flag,可以比较容易的检查每个人的位置编号
每个人有两个属性 bf 和 next 表示他的前驱和后继
每次遇到需要被 选中去厨房的人x的时候
x的bf 的next =x的next,x的next的bf=x的bf,还是得用临时变量,并且都针对移动前的。
用 flag记录人的位置编号,如果flag==当前幸运数字,该人被派去厨房,并且flag=0;否则flag++;
如果每次输入n之后计算一次TLE

预处理打个表就好了...模拟的还是不够v5

#include<stdio.h>int next[33820],bf[33820],zz=2,ans[30005]={0,2};int main(){    int n,i,m,r,l;    for(i=2;i<=33809;i++){            next[i]=i+1,bf[i]=i-1;        }        int st=2;        for(int j=0;j<3000-1;j++){            int flag=1;            for(i=next[st];i<=33809;i=next[i]){                if(flag==st){                r=next[i],l=bf[i];                next[l]=r,bf[r]=l;                flag=1;                }else flag++;            } st=next[st];            ans[zz++]=st;        }        ans[zz++]=st;      while(scanf("%d",&n)!=EOF){      printf("%d\n",ans[n]);    }    return 0;}





原创粉丝点击