题目描述
小朋友们在玩游戏:2k个小朋友围成一个圈,标号依次从1到2k,其中k个扮演好人,另k个扮演坏人。游戏规则如下:从第一个小孩开始报数,报到m时,第m个小孩被踢出,然后从下一个小孩开始,重复前面的过程,直到还剩下k个小孩,停止踢人。我们希望被踢出的都是坏人。已知前k个是好人,后k个是坏人,现在要求你对于每一个k,确定一个最小的正整数m,使得按游戏规则踢出的k个孩纸都是坏人。
关于输入
输入有多行,每行一个非负整数k,k不大于13。若输入为0,则标志着输入结束。
关于输出
对于每一个正整数k,输出最小的m
例子输入
1
4
0
例子输出
2
30
提示
这道题很容易timeout
源码实现
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int ans[10000] = {0};
bool a[30];
int main(){
int k;
int countans = 0;
while (1) {
cin >> k;
if (k == 0)break;//数据以0为结束符
int m;
for (m = 1 + k;; m++) {
if (m % (2 * k) == 1)
m += k;//避免踢出的第一个孩子就是好人
memset(a, 0, sizeof(a));//memset直接对内存进行操作效率会相对高一点
for (int i = 1; i <= 2 * k; i++) {
a[i] = 1;
}//初始化,a[i]=1说明a[i]都还在场
int j;
int index = 0;
for (j = 0; j < k; j++) {
for (int i = 0; i < (m-1+2 * k - j) %(2*k-j)+1; i++) {
//这个%后面的那一堆是现在剩下的人数
//比如说要报km+n个数,只需要报n个数就好(n=1,2,3,…,m)
if (index == 2 * k)
index = 1;
else
index++;
while (!a[index]) {
if (index == 2 * k)
index = 1;
else
index++;
}
}
a[index] = 0;
if (index >= 1 && index <= k)
break;
}
if (j == k) {
break;
}
}
ans[countans] = m;
countans++;
}
for (int i = 0; i < countans; i++) {
cout << ans[i] << endl;
}
return 0;
}