• POJ 1012 Joseph


    题意:有k个好人和k个坏人进行约瑟夫环问题,好人在前面,坏人在后面(即好人编号为0...k - 1),求一个最小的m,使他们用m报数时所有坏人在有好人出局之前出局

    解法:一开始没怎么细想就写了个模拟……果断T了……于是想把结果打表……结果发现k = 13时根本跑不完……

    于是还是枚举m,推导每次出局的人,并在线打表。

    以n = 6, m = 5举例:

    一开始序列为0, 1, 2, 3, 4, 5

    第m%n个人出局,对应的编号为(m + 1) % n

    从出局后面的人开始报数,则队列变为:

    5, 0, 1, 2, 3重新编号则变为:

    0, 1, 2, 3, 4

    此时人数n减少了1

    则第m%(n - 1)个人出局,对应的编号为(m + 1) % (n - 1)

    设上一轮出局的人编号为x,本轮编号从上一轮出局的人的后一人开始,所以反推回去本轮出局的(m + 1) % (n - 1)在上一轮的编号为(x + (m + 1) % (n - 1)) % (n - 1)

    化简得到(x + m + 1) % (n - 1)

    这是对于第二轮来说的,每轮的人数都会减少,第k轮的时候人数为n - k + 1

    所以最终的通项公式为f[0] = 0, f[i] = (f[i - 1] + m + 1) % (n - k + 1),f[i]的含义为第i轮出局的人的编号

    那么只要判断前k轮有没有好人出局就可以了,一旦有好人出局则继续枚举m,没有好人出局则为答案

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    int main()
    {
        int jos[14] = {0};//在线打表,避免反复求解
        int n;
        while(~scanf("%d", &n) && n)//n即为上面说的k,2 * n为上面说的n(变量名起的这么奇幻真的好么)
        {
            if(jos[n])
            {
                printf("%d
    ", jos[n]);
                continue;
            }
            int m = 1;
            while(1)
            {
                int f = 0;
                int i = 1;
                for(; i <= n; i++)
                {
                    f = (f + m - 1) % (2 * n - i + 1);
                    if(f < n)
                    {
                        m++;
                        break;
                    }
                }
                if(i > n)
                {
                    jos[n] = m;
                    printf("%d
    ", m);
                    break;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    【干货】如何5分钟内解决实时输入仿真(超简单)
    我们不生产bug,我们只是算法的搬运工——OO第一次作业(踩雷)总结
    OO助教总结
    oo第四次总结作业
    oo第三次总结性作业
    OO第二次总结性作业
    oo第四次作业
    C++学习记录二:
    长沙.NET社区之光
    课程总结
  • 原文地址:https://www.cnblogs.com/Apro/p/4455626.html
Copyright © 2020-2023  润新知