ccf201712-2 游戏 90分代码

先上题目:

cb1fce1d801c4eddaa5b0de97b2436d4.png

 这道题一开始做的时候没认真审题,当成报数题做了,提交了几个0分发现问题不在代码,于是重新读了遍题。发现跟普通的报数不同的是,当一个人报出目标数后就会淘汰,于是就造成了循环周期的两个需求:

1.当前淘汰目标的下一个人需要接着他的数报 2.当前循环周期的下一个循环需要接着上一个周期的数字报,且周期-1

这需要数组能够记录每次报数的淘汰情况,并每更新一轮新的情况,就将原来的情况(称之为残局)覆盖。所以一维数组即可。数组的下标为选手的标签,数值则为所报数。这样每淘汰一人,数组就少一个元素,剩下的幸存者向前补位(补位过程只需一个简单的for遍历即可实现),直到只剩一个人时,数组的首元素即为winner。

为了让模拟容易实现,我还引入了工具tmp,num,pm,strat。具体作用是实现当前选手是当前周期的第几人,那么他就报自己的序号。有些复杂,读者可以在标程中慢慢理解。


标程

int main() {

    int n = 0,k=0;

    cin >> n>>k;

    int cnt = 0;

    int c;

    int start = n;

    int num = 1;

    int m = n;//m是当前幸存者

    int pm = 0;

    int z[5+1] = { 0 };//记录每次报数残局 

    //每次一轮结束后(遍历走过了当前人数次) 更新淘汰人数(带标签) 不更新报数

    //初始化第一轮 所有人都没被淘汰

    for (int i = 0; i < n; i++) {

        z[i] = i + 1;

    }

    while (m != 1) {

        c = 0;

        for (int i = 0; i < start; i++) {//遍历到本次周期的第i个 

            //所报数从第一个人开始 依次+1 不更新

            if (num % k == 0 || num % 10 == k) {//第tmp人淘汰

                int tmp = num;

                tmp = num - pm;//实现这个人是第几个 他就报序号(下标+1) 

                //每淘汰一个人 就把这个人记作-1

                z[tmp-1] = -1;//tmp-1是因为下标0 

                m--;

            }

            num++;

        }

        //模拟补位过程 其中start是这一轮开始时的人数 初始化为n

        for (int i = 0; i <start; i++) {

            if (z[i] != -1) {

                z[c++] = z[i];

            }

        }

        pm += start;

        start = m;

        //pm实现存迄今为止所有残局 这样num-pm使报数总从1开始

        //z实现存每次残局 按序只存赋值为-1的

        cnt++;

    }

    cout << z[0];

    return 0;

}


这样能拿到九十分,超时代码。还没有想出优化方案,有大佬可以指点一下嘛

其实这个题早就写了,学期太忙拖到现在才写博客,要不是有注释已经看不懂自己写的什么意思了,注释真是个好东西啊🥰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值