hdu1443 Joseph---约瑟夫环

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1443

题目大意:

一共有2k个人,分别为k个好人和k个坏人,现在我们需要每隔m个人把坏人挑出来,但是条件是最后一个坏人挑出来前不能有好人被挑出来。。问最小的m是多少。k最大为13.

思路:

由于k的数值较小,直接打表就行。

对于约瑟夫环问题一般都是由0-n-1的下标,并且start = (start + m - 1)% n(n为当前的人数,n是会不断地变化的)这里的start是下标!!!不是具体的数值

举个例子:

6个人步数为5,初始化,start = 0

第一次:start = 0 + 5 - 1 % 6 = 4,下标为4的编号剔除

下标:0 1 2 3 4 5

编号:1 2 3 4 5 6

 

第二次:start = 4 + 5 - 1 % 5 = 3,下标为3的编号剔除

下标:0 1 2 3 4

编号:1 2 3 4 6

 

第三次:start = 3 + 5 - 1 % 4 = 3,下标为3的编号剔除

下标:0 1 2

编号:1 2 3 6

这里表示的都是下标的变化,题目要求前k个人不能先被剔除,只要下标start >= k一直成立就可以保证不会剔除前k个。因为如果每次的start >= k,说明提出的编号一定是>=k的(这里编号为k表示第k+1个人)

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn = 1e5;
 7 ll a[25];
 8 void init(int k)
 9 {
10     for(int ans = 0; ; ans++)//枚举步数
11     {
12         int start = 0;
13         int n = 2 * k;//2*k个人
14         bool ok = 1;
15         while(n > k)//输出前n个人即可
16         {
17             start = (start + ans - 1) % n;//这是下标,不是具体的数值,但是此处的下标必须大于等于k,这样才能保证前k个人不被剔除
18             //cout<<start<<endl;
19             if(start < k)//下标 < k,说明输出的一定是前k个人中的某一个
20             {
21                 ok = 0;
22                 break;
23             }
24             else n--;//满足的话,人数减一
25         }
26         if(ok)
27         {
28             a[k] = ans;
29             return;
30         }
31     }
32     return;
33 }
34 int main()
35 {
36     int n;
37     for(int i = 1; i <= 13; i++)init(i);
38     while(cin >> n && n)
39     {
40         cout<<a[n]<<endl;
41     }
42     return 0;
43 }

约瑟夫环传送门(等写到那个地方就开启传送门)

 

转载于:https://www.cnblogs.com/fzl194/p/8684818.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值