Joseph problem two solutions

Title Description

Numbered from 1 to N, the N children playing game played in a loop. Children at the beginning of a circle of N, stand for the number of I + 1 number of children left I children. Number standing in a children number N of children left. First, number of children a start packet number, then the number of children standing order of packets to the left until the ring lies to a digital number M. Until only one child, the game is completed.

Now given N, M, find the children of the N ring sequence.

Input Format

The only line contains two integers N, M. (1 <= N, M <= 30000)

Output Format

The only line containing N integers, each of the two intermediate integers separated by a space, the I-th integer I-th number of children a circle

Sample

Sample input

5 3

Sample Output

3 1 5 2 4

简单来说,就是每次删除一个人,输出,继续循环一直输出到只剩最后一个人,输出。
如果要输出最后一个人,前面的输出直接省去就可以了
#include <the iostream> 
#include <cstdio>
 the using  namespace STD;
 int main () 
{ 
    BOOL m [ 30001 ]; // save whether each person is still alive, alive to false, true dead 
    int A, B; // A personal, b the ring 
    CIN >> A >> b;
     for ( int I = . 1 ; I <= A; ++ I) 
        m [I] = to false ; // all alive 
    int C = 0 , D = 0 , E = 0 ; // D is the current number of packets 
    do 
    {
         ++C;
         IF (A + C == . 1 ) // If after the last one, back to the first, analog cyclic 
            C = . 1 ;
         IF (m [C] == to false ) // If alive, reported number 
            ++ D;
         IF (D == B) 
        { 
            D = 0 ; // zero 
            COUT C << << "  " ; // If just the last one, eliminating the need for 
            m [C] = to true ; // that man was dead. . . . 
            ++ E; 
        } 
    } the while(E = A!); // if dead, out 
}

This is a simple version of the above, the time complexity is O (n2)

The following is burning brain, ready to catch

Joseph problem 2 solved

 

Title Description

 

Joseph problem is a famous problem: N personal circle, the number of starting from the first report, the first of M will be killed, the last remaining one, the rest will be killed. Please write a program to determine the final number of people who will be left.

Input Format

Only input line for two integers n, m (0 <n, m <10 ^ 8).

Output Format

Only one line, a number, as the last remaining person's number

Sample

Sample input

6 5

Sample Output

1
这个问题你们看到了数据规模很大n2绝对超时
当N的值有上百万,M的值为几万时,到最后虽然只剩2个人,也需要循环几万次(M的数量)才能确定2个人中下一个出列的序号。显然,在这个程序的执行过程中,很多步骤都是进行重复无用的循环。
现在有一个强大的数学规律
解析:
  其中,在约瑟夫环中,只是需要求出最后的一个出列者最初的序号,而不必要去模拟整个报数的过程。因此,为了追求效率,可以考虑从数学角度进行推算,找出规律然后再编写程序即可。
  我们从0开始循环(从零开始报数),到n-1,共n个人,第一个出圈的人是报数m-1的,所以他的编号是m-1或(m-1)%n(因为是从零开始,所以不用考虑+1问题)
  现在有n-1个人,从0循环到n-2(已经出圈的人的空位删掉),报数现在(删掉空位后)从(m-1)%n报0,1,2,3,4...。(m-1+
(m-1)%n)%(n-1)出圈,每一次都模现在的人数。
  实际上就是一层层的模
  现在我们逆推,假设现在只剩下1人,出圈的肯定是0号。
  
  设f=0,f是最后活的那个人在只剩下一个人的环中的编号
  现在进入两个人的环,报m-1的出圈,他就是当时的第m个,所以他在两个人的圈中的编号就是f+m,由于人数可能少于m,所以要用模,f=(f+m)%n n=2;
  然后进入三个人的圈,m-1继续出圈,他是第m个,在上一圈里,他是f,所以f=(f+m)%n n=3;
  以此类推,n=4,5,6,7,8......
  因为题中是从1开始报,所以在算出n个人的圈中,那个人的编号f后,要+1;
  
  程序很简单,一个循环就搞定;
  
#include <the iostream>
 the using  namespace STD;
 Long  Long n-, m, F; // automatically assigned zero outside 
int main () 
{ 
    CIN >> >> n- m;
     for ( int I = 2 ; I <= n-; ++ i) // with i count the number 
        F = (F + m)% i; 
    F ++ ; 
    COUT << F; 
}

   Little insight, the god of exhibitions

 

Guess you like

Origin www.cnblogs.com/fengwu2005/p/11269222.html