POJ 1012 Joseph
2013-09-16 22:42
267 查看
问题描述:
假设有k个好人和k个坏人,围成圈坐着,前k个人是好人,后k个人是坏人。必须选定一个最小的m值,使得在第一个好人选出之前,所有的坏人全部死了。
输入描述:
输入包括若干行,每一行都是一个数,即k,0<k<14。输入最后一行为0,表示输入结束。
输出描述:
每一行输出对应于k值的m值。
都说Joseph是一个经典,但是对于我这种以前没接触过的来说,哪算是经典啊。于是又去百度,找资料了解经典Joseph问题的解法。经典Joseph问题最简单的算法应该是数学方法:
f[0]=0;
f[i]=(f[i-1]+m)%i;
要得到f[i]的必须先计算f[i-1]的值,要得到f[i-1]的值又要先计算f[i-2]·····依此类推。于是有:
for(i=2;i<=n;i++)
{
s=(s+m)%i;
}
对于经典Joseph问题,只需要求出最后一个获胜者,因此数学法是相当简单的。但是,数学法不能输出淘汰的过程。
此题是Joseph的变形,要算出最小m值,只能遍历,至少现在没看见更好的方法。遍历的方法还是主要通过相应的数学公式迭代,只要算出的f(i)<k,就跳出此次循环,m增1,进行下一次循环,知道循环k轮。
递推公式:f[0]=0;
f[i]=(f[i-1]+m-1)%(n-i+1)
值得注意的是,f[i]是当前序列中要退出的人的序列号,从0开始,例如:
k=4 m=30
f[0]=0;
f[1]=(f[0]+30-1)%8=5;此时序列为(0,1,2,3,4,5,6,7),第5个数是5
f[2]=(f[1]+30-1)%7=6;此时序列为(0,1,2,3,4,6,7),第6个数是7
f[3]=(f[2]+30-1)%6=5;此时序列为(0,1,2,3,4,6),第5个数是6
·············
在此题中,要求先排除的是后k个,因此必须根据递推出的公式算出f(i)>k,否则退出循环。
在程序中需要,将已经计算的数据添加到一张表中,否则会TLE。在网上,还看见了有大牛提出,m不需要每次递增,m是k+1的整数倍或k+1的整数倍加1,因此,每次的m可以增加k+1,可以增速不少。
假设有k个好人和k个坏人,围成圈坐着,前k个人是好人,后k个人是坏人。必须选定一个最小的m值,使得在第一个好人选出之前,所有的坏人全部死了。
输入描述:
输入包括若干行,每一行都是一个数,即k,0<k<14。输入最后一行为0,表示输入结束。
输出描述:
每一行输出对应于k值的m值。
都说Joseph是一个经典,但是对于我这种以前没接触过的来说,哪算是经典啊。于是又去百度,找资料了解经典Joseph问题的解法。经典Joseph问题最简单的算法应该是数学方法:
f[0]=0;
f[i]=(f[i-1]+m)%i;
要得到f[i]的必须先计算f[i-1]的值,要得到f[i-1]的值又要先计算f[i-2]·····依此类推。于是有:
for(i=2;i<=n;i++)
{
s=(s+m)%i;
}
对于经典Joseph问题,只需要求出最后一个获胜者,因此数学法是相当简单的。但是,数学法不能输出淘汰的过程。
此题是Joseph的变形,要算出最小m值,只能遍历,至少现在没看见更好的方法。遍历的方法还是主要通过相应的数学公式迭代,只要算出的f(i)<k,就跳出此次循环,m增1,进行下一次循环,知道循环k轮。
递推公式:f[0]=0;
f[i]=(f[i-1]+m-1)%(n-i+1)
值得注意的是,f[i]是当前序列中要退出的人的序列号,从0开始,例如:
k=4 m=30
f[0]=0;
f[1]=(f[0]+30-1)%8=5;此时序列为(0,1,2,3,4,5,6,7),第5个数是5
f[2]=(f[1]+30-1)%7=6;此时序列为(0,1,2,3,4,6,7),第6个数是7
f[3]=(f[2]+30-1)%6=5;此时序列为(0,1,2,3,4,6),第5个数是6
·············
在此题中,要求先排除的是后k个,因此必须根据递推出的公式算出f(i)>k,否则退出循环。
void main() { int k,m; int i,s; int buffer[15]={0}; while(scanf("%d",&k)!=EOF) { m=k+1; if(k==0) break; while(1) { s=0; if(buffer[k]>0) { m=buffer[k]; break; } for(i=1;i<=k;i++) { s=(s+m-1)%(2*k-i+1); if(s<k) { m++; break; } } if(i==k+1) { buffer[k]=m; break; } } printf("%d\n",m); } }
在程序中需要,将已经计算的数据添加到一张表中,否则会TLE。在网上,还看见了有大牛提出,m不需要每次递增,m是k+1的整数倍或k+1的整数倍加1,因此,每次的m可以增加k+1,可以增速不少。
相关文章推荐
- [POJ][1012]Joseph
- poj 1012 Joseph
- poj 1012 Joseph解题报告
- POJ 1012 Joseph 推导,暴力,约瑟夫环,打表 难度:2
- poj 1012 Joseph
- poj 1012 & hdu 1443 Joseph(约瑟夫环变形)
- POJ 题目1012Joseph(数学,约瑟夫环)
- POJ 1012 Joseph
- Joseph - POJ 1012 打表
- POJ 1012:Joseph
- poj 1012 Joseph
- Poj1012_Joseph
- POJ 1012 Joseph
- poj1012 Joseph
- POJ 1012 Joseph 变形约瑟夫环
- poj 1012 -- Joseph (约瑟夫环)
- POJ 1012:Joseph
- poj1012-Joseph
- POJ1012 Joseph
- Poj1012_Joseph