题意:
有k个坏人k个好人坐成一圈,前k个为好人(编号1~k),后k个为坏人(编号k+1~2k)
现在有一个报数m,从编号为1的人开始报数,报到m的人就要自动死去。
问当m为什么值时,可以使得在出现好人死亡之前,k个坏人先全部死掉?
已知:k,n=2*k
求:m
分析:例子 k=3,n=6,m=5
1 2 3 4 5 6
以m=5为一循环长度报到m的编号依次为:5,4,6,2,3,1
就是长为n的数组以m为循环长度进行循环,输出报到m的编号
1 2 3 4 5 6 (黑体为报开始循环1的编号)
1 2 3 4 6
1 2 3 6
1 2 3
1 3
1
符合以下规律公式:ans[i]=(ans[i-1]+m-1)%(n-i+1)+1; //ans[0]=0
注明:ans[i]中的i是指第i次报到m,其值ans[i]是指第i次报到m的编号
该规律公式法代码:
#include<iostream> using namespace std; int main() { int k; int jos[15]={0}; while(cin>>k&&k!=0) { if(jos[k]!=0) cout<<jos[k]<<endl; else { int n=2*k; int m=k+1;//如果m<=k,那么第一次杀的一定是好人 int ans[30]; ans[0]=0; for(int i=1;i<=k;i++)//循环需要杀坏人的次数 { ans[i]=(ans[i-1]+m-1)%(n-i+1); if(ans[i]<k) { i=0,m++; } } jos[k]=m; cout<<jos[k]<<endl; } } }
另一种方法:
#include<iostream> using namespace std; bool result(int k,int m) //检测m是否符合 { int mod=0; int n=2*k; for(int i=0;i<k;i++) { mod=(mod+m-1)%(n-i);//n-i是圈子余下的人数,以这个为实际圈子长度 //m是循环长度 m-1是因为都是从0开始的 mod是上一个数的位置 if(mod<k) return false; } return true; } int main() { int k; int data[14]={0}; while(cin>>k&&k!=0) { if(data[k]!=0) cout<<data[k]<<endl; else { int m=k+1; while(result(k,m)==0) { m++; } data[k]=m; cout<<m<<endl; } } return 0; }