poj 1012 Joseph

[color=blue][size=medium]
题目描述:[url]poj.org/problem?id=1012[/url]

经典Joseph 问题的加强版, 参见注释, 注释很详细.
[/size][/color]

#include <cstdio>

/*
 测试m是否满足要求
 k: 有2k个人
 m:每数到m就出局 */
bool test(int k, int m) {
int i = 0, len = 2 * k; //len: 当前总人数
while(len > k) {
i = (i + m - 1) % len; //每次出局人是出局前的len 个人中的第i 个, 下标从0 开始
if(i < k)
return false;
len--; //没出局一个,修改len
}
return true;
}

int main() {
int k;
int a[14] = {0}; //数组保存计算过的数据, 不保存的话会超时,
//其实很无聊,就14个数据,还整这么大的数据量
while(scanf("%d", &k) && k) {
if(!a[k]) { //如果a[k]为0 就进行测试
int t = k + 1; //测试从k+1开始,下于K+1的测试没必要
while(true) {
if(test(k, t)) {
a[k] = t;
break;
}
else
t++;
if(t == 2 * k)//跳过不必要的测试
t += k + 1;
}
}
printf("%d\n", a[k]);
}
return 0;
}

[color=red][size=medium]
还有"猥琐"点的做法,因为就 14个数据, 直接把数据存到数组中即可
[/size][/color]

#include <cstdio>
int main() {
int k,a[15]= {0, 2, 7, 5, 30, 169, 441, 1872, 7632, 1740, 93313, 459901, 1358657, 2504881, 14};
while(scanf("%d", &k), k)
printf("%d\n", a[k]);
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值