您的位置:首页 > 其它

POJ 1012 Joseph

2012-05-07 23:13 309 查看
POJ 1012 Joseph

算法解析:本来我想用链表或者数组来模拟这个Joseph链,后来发现因为题目并没有要求输出每一次报数排除的人的号码且前k个人是好人不能被排除,因此不需要那么复杂的模拟,仅需要每次剔除一个人以后重新组成Joseph链(可以看成我们不关心每个人起初对应的号码是多少,只关心现在链中有多少人及现在报数的位置);另外需要注意的是报数m仅仅可能是m%(k+1)=0 或1——这个是剔除最后一个坏人所必须满足的报数条件。

算法代码实现:需要注意的是必须将1-13存入数组以便调用(如果直接利用输入计算的话会超时,估计是因为有大量重复输入的存在),因此可以看出当枚举个数较小时,我们可以先计算出结果暂时存储,以便之后的调用。

算法代码:

#include <iostream>
using namespace std;

//用于记录1-14的对应报数值
int m[14];

//当有2k个人,报数为m时返回是否符合条件
bool Judge(int k, int m)
{
//len为队列当前长度值
int len=2*k;
//i为当前报数到的人的编号,从0开始编号
int i=0;
while (len>k)
{
i=(i+m-1)%len;
if (i<k)
{
return false;
}
len--;
}
return true;
}

//求出当有2k个人时的报数值
int Number(int k)
{
int i=k+1;
while (1)
{
if (Judge(k, i))
{
return i;
}
if (Judge(k,i+1))
{
return i+1;
}
i+=(k+1);
}
}
//将1-14的对应报数值存储在m[14]中
void GetNumber()
{
for (int i=1; i<14; i++)
{
m[i]=Number(i);
}
}

int main()
{
//注意必须存成数组,否则会超时(估计是测试集中有很多重复数字)
GetNumber();
int k;
while (cin>>k && k)
{
cout<<m[k]<<endl;
}
return 0;
}

参考资料:
点击打开链接:我是看了这个报告才反应过来可以不需要用数组或者链表而直接使用一个数字来模拟问题...

点击打开链接:这个报告写得很详细,但是也很繁琐....我仅仅用它的最后计算数据来验证我的算法写对没有....
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 存储 测试