51nod 1875 丢手绢(模拟)

xiaoxiao2021-02-28  101

1875 丢手绢 六一儿童节到了,小朋友们在玩丢手绢的游戏。总共有C个小朋友,编号从1到C,他们站成一个圈,第i个人的左边是i-1,第1个人的左边是C。 第i个人的右边是i+1,第C个人的右边是1。然后再给出一个常数E。刚开始的时候1号小朋友拿着手绢,接下来游戏开始, 在游戏的每一轮,拿手绢的人会把手绢向右边传递E-1个人,拿到手绢的人退出圈,把手绢递给他右边的小朋友,剩下的人向中间挨紧, 把圈中的空位补满。然后开始下一轮,如此往复。直到圈中只剩一个人。比如C=6,E=5的时候,出圈的顺序是5,4,6,2,3,最后1号小朋友留在了圈中。 现在有2G个小朋友,要求一个最小的常数E,使得这2G个小朋友玩了G轮游戏之后,出圈的小朋友编号刚好是G+1到2G。

Input 多组测试数据。 每一行给出一个整数G( 0 < G < 14),G=0的时候表示输入结束。 Output 输出多行,表示每一组数据的答案。 Input示例 3 4 0 Output示例 5 30

/** *对于每一个G,判断E是否满足条件 *模拟操作G次之后,判断时候[G+1,2G]全部出局 */ #include<iostream> #include<list> #include<vector> #include<algorithm> using namespace std; const int MAXN = 15; //模拟,判断E时候合适 bool check(int G,int E){ if(1+E<G) return false; vector<int> vec; for(int i=1;i<=2*G;i++){ vec.push_back(i); } int vis[2*MAXN] = {0}; int now = 0,next,len = 2*G+1; for(int i=0;i<G;i++){ next = (now+E-1)%(vec.size()); vis[vec[next]] = 1;//标记删除的值 //cout<<next<<" "<<vec[next]<<endl; vec.erase(vec.begin()+next); now = next % (vec.size()); //cout<<now<<endl; } //检查 for(int i=G+1;i<=2*G;i++){ if(!vis[i]) return false; } return true; } //模拟得到的结果 const int E[] = {0,2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881}; int main() { int G; while(cin>>G && G){ // cout<<check(G,30)<<endl; //记录1-3的值 /**得到结果 for(int i=1;i<=13;i++){ int E=2; while(!check(i,E)) ++E; cout<<E<<","; } **/ cout<<E[G]<<endl; } return 0; }
转载请注明原文地址: https://www.6miu.com/read-39807.html

最新回复(0)