http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid=2§ionid=2&problemid=2
题意:有2k个人,前k个是好人,后K个是坏人。每次干掉一个,要求全部坏人被干掉前不能有好人被干。
人员按0…… 2k-1的顺序编号,方便计算。
本题可简单地把人员编号分成两类,0……k-1为好人,若得出此范围内的编号,则好人被杀,不符合要求,进行下一轮迭代。
若编号为k……2k-1,则坏人被杀,总人数减1,。因为坏人都是一样的,此时可以将编号为最后一个的坏人替代本轮被杀的坏人。
于是坏人的编号为k……sum-1.
(j + m - 1)% sum == 0对应于第一个人。
需要减1的原因在于,上一轮该编号的人已死,本轮该编号的人为另外的坏人,所以减1指向前一个人,一个上一轮已经数过的人。
#include <stdio.h>
int res[15];
int fun(int k)
{
int sum;
int m;
bool flag;
if(res[k])
return res[k];
for(m = k + 1; ;m++) //m不可能小于k
{
sum = 2 * k;
int j = 0;
while(1)
{
j = (j + m - 1) % sum;
sum--;
if(j < k) //编号小于k说明是好人
{
flag = false;
break;
}
if(sum == k) //sum等于k说明只剩好人
{
flag = true;
break;
}
}
if(flag == true)
{
res[k] = m;
return res[k];
}
}
}
int main()
{
int k;
while(scanf("%d",&k) != EOF && k)
{
printf("%d\n", fun(k));
}
return 0;
}