题干:

六一儿童节到了,小朋友们在玩丢手绢的游戏。总共有C个小朋友,编号从1到C,他们站成一个圈,第i(1<i<=C)个人的左边是i-1,第1个人的左边是C。第i(1<=i<C)个人的右边是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

输出多行,表示每一组数据的答案。

Sample Input

3
4
0

Sample Output

5
30

解题报告:

预处理打表过即可。

主要是学习一下vector处理这种问题的方法。

vector放入数据之后。

开始遍历

设置一个变量为当前值,一个变量为变化后的值。

变化后的值为 (当前值+移动数-1)%(vector数组的大小)

让vis数组标记下变化后的位置的值,表示已经被剔除了。

执行vector.earse(vector.begin()+ 变化后的值),在vector中删除这个值。

之后让当前值 等于 变化后的值。

一个循环结束,重复即可。

先上一个非常不清真的代码:

#include<bits/stdc++.h>using namespace std;
bool vis[105];
int n,res,cur;
bool solve(int e) {memset(vis,0,sizeof(vis));int i=1;cur = 0;while(i <= (n/2)) {//这里的while也太不清真了、、 int num = 0;while(1) {if(vis[cur]==1) {cur=(cur+1)%n;continue;//这写的太不清真了,变量加减太随意。很容易出漏洞啊!!包括那种,高速路加油问题,变量的变化的地点要清真一点! }cur=(cur+1)%n;if(vis[cur] == 1) continue;num++;if(num == e) {if(cur < (n/2)) return 0;vis[cur]=1;do{cur=(cur+1)%n; }while(vis[cur]);break;}}i++;}return 1;
}

所以各种无输出啊死循环啊的情况、、、

改进以后

bool solve(int e) {memset(vis,0,sizeof(vis));cur = 0;for(int i = 1; i<=(n/2); i++) {int num = 0;while(1) {cur=(cur+1)%n;if(vis[cur] == 1) continue;num++;if(num == e) {if(cur < (n/2)) return 0;vis[cur]=1;do{cur=(cur+1)%n;  }while(vis[cur]);break;}}}return 1;
}
int main()
{int ans[20] = {0,2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881};while(cin>>n) {if(n == 0) break;printf("%d\n",ans[n]);}return 0 ;} 

算是可以输出了,但是e从2到1000W遍历的耗时太长啦!所以标解肯定不是这么做的、、说明我们的模拟有问题,然后换了STL中的vector模拟这个过程,去掉一些无用的过程。

还有一种比较快的方法:(类似约瑟夫环的解法,不知道为什么可以这样)

#include<bits/stdc++.h>using namespace std;
typedef long long ll;
const int maxn = 1e3+5;
pair<int,int> pr;
int arr[maxn];
int n;
int ans[20] = {0,2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881};
bool judge(int k)
{int m = 2*n, cur = 1;for(int i=0; i<n; i++){cur = (cur+k)%m;cur==0 ? cur=m : cur=cur;if(cur<=n)return false;m--;}return true;
}
int main( )
{init( );while(cin>>n && n!=0){for(int i=n; ;i++){if(judge(i)){cout<<i+1<<endl;break;}if(i%(2*n)<n)i += n-1;}//cout<<ans[n]<<endl;}return 0;
}

下面是用vector模拟的过程:

#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;vec.erase(vec.begin()+next);now = next % (vec.size());}//检查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;    //记录1-3的值/*得到结果**/for(int i=1;i<=13;i++){int E=2;while(!check(i,E)) ++E;cout<<E<<",";}while(cin>>G && G){cout<<E[G]<<endl;}return 0;
}

【51nod - 1875】 丢手绢(约瑟夫问题,可打表,用STL模拟)相关推荐

  1. 1875 丢手绢 约瑟夫环变形 枚举

    1875 丢手绢 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 六一儿童节到了,小朋友们在玩丢手绢的游戏.总共有C个小朋友,编号从1到C,他们站成一个 ...

  2. 51nod 1875 丢手绢

    六一儿童节到了,小朋友们在玩丢手绢的游戏.总共有C个小朋友,编号从1到C,他们站成一个圈,第i(1<i<=C)个人的左边是i-1,第1个人的左边是C.第i(1<=i<C)个人的 ...

  3. 51nod1875丢手绢

    https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1875 1875 丢手绢  基准时间限制:1 秒 空间限制:131072 ...

  4. 51nod-1875 丢手绢

    1875 丢手绢  基准时间限制:1 秒 空间限制:131072 KB 分值: 20  难度:3级算法题  收藏  关注 六一儿童节到了,小朋友们在玩丢手绢的游戏.总共有C个小朋友,编号从1到C,他们 ...

  5. 数据结构与算法--我们来玩丢手绢(约瑟夫环问题)

    我们来玩丢手绢 昨天我们打扑克,今天我们丢手绢 丢手绢我们都知道这个游戏,他的由来由约瑟夫 (Josephus)提出来的 据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,3 ...

  6. 数据结构与算法: 约瑟夫问题(丢手绢)

    数据结构与算法: 约瑟夫(丢手绢)问题(单向链表,双向链表解决) Tips: 采用java语言, 关注博主,底部附有完整代码 采用到的知识点: 单向环形链表 双向环形链表 单向 / 双向 环形链表出圈 ...

  7. C++约瑟夫环(又称丢手绢)解决---最简单的理解

    首先约瑟夫环的定义: 在一间房间总共有n个人(下标0-n-1),只能有最后一个人活命. 按照如下规则去排除人: 所有人围成一圈, 从0开始 顺时针报数, 每次报到m的人将被排除掉 被排除掉的人将从房间 ...

  8. 约瑟夫环 -- 丢手绢问题

    问题描述 约瑟夫环问题,也称为"丢手绢问题". 编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3-这样依次报),数到 m 的 士兵 ...

  9. Java数据结构单向循环链表实现约瑟夫问题(丢手绢)

    环形链表 实例:使用环形链表解决约瑟夫问题(丢手绢) 构建一个单向环形链表思路 ​ 1)先创建第一个节点,让first指向该节点,并形成环形 ​ 2)加入环形链表 遍历环形链表 ​ 1)先让一个辅助指 ...

最新文章

  1. RabbitMQ -- Hello world
  2. rest laravel_如何通过测试驱动开发来构建Laravel REST API
  3. pom.xml 配置之:snapshot 快照库和 release发布库 的区别
  4. 数据重现之11.5.2:RAID5同步与异步的判断
  5. Go 语言基础(三)——基本数据类型
  6. 使用Excel公式,获取 全路径中 的 文件名
  7. Python发布自己的模块到Pypi
  8. 解决 Win7 远程桌面 已停止工作的问题
  9. VSLAM算法(二):PnP求解 3D-2D 相机位姿及 BA优化算法
  10. 强化学习10——迭代学习
  11. miui11稳定版获取完整root_MIUI11系统怎么样刷入开发版获得Root超级权限
  12. 2018年年度总结-工作成长
  13. Matplotlib画图的复杂颜色设置(包括fig, ax, spines, tick)
  14. 零基础入门数据挖掘-Task3 特征工程
  15. fatal: unable to access ‘https://github.com/NEGVS/the-economist-ebooks.git/‘: schannel: failed to re
  16. 制作手机远程控制开关
  17. HACKTHEBOX——Nibbles
  18. 运行时数据区-堆(Heap)
  19. 魔兽世界-战士的真谛
  20. ZYPlayer隐藏功能!再不看就被删掉了!

热门文章

  1. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第34篇]描述攻击离散对数问题的baby-step/Giant-step方法
  2. [Leetcode][第63题][JAVA][不同路径2][动态规划][压缩路径]
  3. python 修改图片尺寸_python 批量修改图片大小
  4. java file 堵塞_单元测试最终在Java 6中阻塞
  5. mysql 创建查询 删除_MYSQL数据库查询删除创建企业基本知识
  6. css加了固定定位就不显示内容_前端开发必备,学好”定位“向菜鸟说拜拜
  7. c语言凸包算法,基于C语言的凸包算法实现
  8. h5 storage事件监听
  9. C语言的putpiel函数,C语言graphics.h函数介绍
  10. java情书_Java情书已写好,就差妹子了!