zoukankan      html  css  js  c++  java
  • Joseph(约瑟夫环)

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

    Joseph

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 1963    Accepted Submission(s): 1194


    Problem Description
    The Joseph's problem is notoriously known. For those who are not familiar with the original problem: from among n people, numbered 1, 2, . . ., n, standing in circle every mth is going to be executed and only the life of the last remaining person will be saved. Joseph was smart enough to choose the position of the last remaining person, thus saving his life to give us the message about the incident. For example when n = 6 and m = 5 then the people will be executed in the order 5, 4, 6, 2, 3 and 1 will be saved.

    Suppose that there are k good guys and k bad guys. In the circle the first k are good guys and the last k bad guys. You have to determine such minimal m that all the bad guys will be executed before the first good guy. 
     
    Input
    The input file consists of separate lines containing k. The last line in the input file contains 0. You can suppose that 0 < k < 14. 
     
    Output
    The output file will consist of separate lines containing m corresponding to k in the input file. 
     
    Sample Input
    3 4 0
     
    Sample Output
    5 30
     
    约瑟夫环:当数据不是很大,直接用链表模拟就可以过,O(n*m)的复杂度 , 及n*m < 10^6 就可以直接用链表做,但是这个题因为要枚举m 故数据太大可以是超出n的值所以没办法用链表
    要是数据大的话要考虑推约瑟夫环公式,现在将n个人重新编号为0~n-1 这样求解的结果要+1  
    下面是使用链表存的一个例子
     1 #include <cstdio>
     2 #include <iostream>
     3 using namespace std;
     4 #define maxn 300
     5 
     6 struct Node{
     7     int v;//存入点的编号 
     8     int next;
     9 }nd[maxn];
    10 
    11 int main()
    12 {
    13     int n, k; 
    14     while(cin >> n >> k)
    15     {
    16         for(int i = 0; i < n; i++)
    17             nd[i].v = i, nd[i].next = i+1;
    18         nd[n-1].next = 0;
    19         
    20         int cur = 0;
    21         for(int i = 0; i < n-1; i++)
    22         {
    23             for(int j = 1; j < k-1; j++) cur = nd[cur].next;
    24             int dnd = nd[cur].next;//要被删除的结点的编号 
    25             nd[cur].next = nd[dnd].next;
    26             for(int j = cur, c = 0; c < (n-i-1); c++, j = nd[j].next) printf("%d ", nd[j].v); puts("");//输出每次剔除人后的环 
    27         }
    28     }
    29     return 0;
    30 }
     
    有第一次的去除的人是(m-1)%n 也可以写成 (m%n)-1 第二次从m%n开始计数,那么要算有n 个人每m个人去除一个,则
    ¡为了方便,在这里我们把这n个人的编号改为从0到n-1,第一个去掉的人总是m%n-1,剩下n-1个人,这n-1个人又组成了一个从第m%n个人开始的新的约瑟夫环问题。
    1 int f(int n,int m)
    2 {
    3   if(n==1) return 0;
    4   else return ((n%m)+f(n-1,m))%n;
    5 }
     

     但是这个题要求是前K 步都要不去除好人所以要统计每次去除的人在原先的编号是多少,

    1 int f(int n , int m , int t)//n 个人 每m 个人提出,第t次去除的是编号为几的人(人的编号从0到n-1)
    2 {
    3     if(t==1) return (m-1)%n;
    4     return (m%n+f(n-1,m,t-1))%n;
    5 }

    下面是ac代码

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 int f(int n , int m , int t)
     5 {
     6     if(t==1) return (m-1)%n;
     7     else return (m%n+f(n-1,m,t-1))%n;
     8 }//n个人,报数到m出列,第t轮出列的人的编号 从0到n-1编号
     9 int res[15];
    10 int main()
    11 {
    12     int n , m , k;
    13     for(int k = 1 ; k <= 13 ;k++)
    14     {
    15         int n = 2*k;
    16         for(m = k+1 ; ; m++)
    17         {
    18             int flag = 1;
    19             for(int i = 1 ; i <= k ; i++)
    20             {
    21                 int cnt = f(n,m ,i);
    22                 if(cnt>=0&&cnt<k)
    23                 {
    24                     flag = 0;
    25                     break;
    26                 }
    27             }
    28             if(flag ) break ;//找到最小的了就不再搜索
    29         }
    30         res[k] = m;
    31     }
    32     while(~scanf("%d",&k),k)
    33     {
    34         printf("%d
    ",res[k]);
    35     }
    36     return 0;
    37 }
  • 相关阅读:
    eclipse luna maven失效的原因
    利用线性探测法解决hash冲突
    PHP和JavaScript将字符串转换为数字string2int
    JavaScript 编程易错点整理
    使用phpstudy创建本地虚拟主机
    单例模式
    PHP使用cookie时遇到的坑
    Redis安装与配置
    CI框架2.x的验证码中所遇问题解决
    用delete和trancate删除表记录的区别
  • 原文地址:https://www.cnblogs.com/shanyr/p/4674212.html
Copyright © 2011-2022 走看看