F - 基础数据结构——单链表(2)(1997-1998 年欧洲西南亚洲区预赛之后,举办了一场隆重的聚会。…………)

题目描述:
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

解题思路:
思路是把每个符合要求的数n(未被剔除的数存在vector res里面), 用mark相应下标的int类型存储从该数开始走的步数step,若step%n==0,则说明该数应该剔除那么就从2开始判断,每次从头遍历res向量中所有的数n,mark[n]++说明从n算起又走了一步,紧接着第进行判断,如果不符合要求直接跳出,避免res中n后面的数的步数也++,这样保证每次出现的num如果要剔除也是因为其最小的因子而被剔除的。

代码实现:

#include <iostream>
#include <vector>
using namespace std;

vector<int> res;
vector<int> ques;
int mark[100000];//注意这里开的是que里面最大的数的人的原来编号的最大范围,他要最大3000,便照着大了开

int main(int argc, const char* argv[]) {
    int num = 1, que = -1, max_que = -1, count = 0;
    bool flag;
    while(cin >> que) {
        ques.push_back(que);
        max_que = max_que >= que ? max_que : que;
    }
    while(num++) {
        flag = true;
        for(int i = 0; i < res.size(); i++) {
            mark[res[i]]++;
            if(mark[res[i]] % res[i] == 0) {
                flag = false;
                break; //这个break是关键,如果碰到n且n是应该去掉的,则比n小的res中的步数都要++,大于n的则不要
            }          //保证了n是由其最小的因数去掉的
        }
        if(flag) {
            res.push_back(num);
            if(res.size() == ques[count]) {
                cout << res[ques[count] - 1] << endl;
                count++;
            }
            if(res.size() == max_que)
                break;
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值