Joseph's question

Source: Internet
Author: User

Problem description: n people (No. 0 ~ (N-1), reporting starts from 0, reporting ends from m-1), and reporting continues from 0. Calculate the number of the winner.

After the first person (number must be (S-1) mod n) is listed, the remaining n-1 individuals form a new Joseph ring (starting with the person numbered k = m mod n ):
K + 1 k + 2... N-2, n-1, 2,... K-2
And 0 is reported from k.
Now let's convert their numbers:
K --> 0
K + 1 --> 1
K + 2 --> 2
...
...
K-2> N-2
After the transformation, it will completely become a subproblem of (n-1) the number of individual reports. If we know the solution of this subproblem: for example, x is the final winner, so it's just n people's situation to change x back Based on the table above ?!! The formula for changing back is very simple. I believe everyone can introduce it: x' = (x + k) mod n
How can I solve the problem of (n-1) number of personal reports? Yes, as long as you know (n-2) the individual's solution. (N-2) What about personal solutions? Of course it is the first (n-3) situation ---- this is obviously a reverse push problem! Well, the idea is coming out. The recursive formula is as follows:
F indicates that I personally play the game and report m to exit the final winner number. The final result is f [n].
Recurrence Formula
F [1] = 0;
F = (f + m) mod I; (I> 1)
With this formula, we need to calculate the value of f from the 1-n order, and the final result is f [n]. Because the number in real life always starts from 1, we Output f [n] + 1


Sub-questions about Joseph.

1. Poj 3517 And Then There Was One

Fixed start point is not 1, but m.

First remove a number, convert it to the n-1 Number of the Joseph Ring problem, and then convert the final result s = (m + s) % n + 1.

 

 

#include <stdio.h>  #include <stdlib.h>  #include <algorithm>  #include <string.h>  #include <math.h>  #include <iostream>  using namespace std;  #define Maxn 10100   int f[Maxn]; int main() {     #ifndef ONLINE_JUDGE      freopen("in.txt","r",stdin);     #endif      int n,m,k;     while(scanf(" %d %d %d",&n,&k,&m)!=EOF)     {         if(n == 0 && m == 0 && k == 0) break;         f[1] = 0;         for(int i=2;i<=n;i++)         {             f[i] = (f[i-1] + k)%i;         }         printf("%d\n",(f[n-1]+m)%n + 1);     }     return 0; } #include <stdio.h>#include <stdlib.h>#include <algorithm>#include <string.h>#include <math.h>#include <iostream>using namespace std;#define Maxn 10100int f[Maxn];int main(){    #ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    #endif    int n,m,k;    while(scanf(" %d %d %d",&n,&k,&m)!=EOF)    {        if(n == 0 && m == 0 && k == 0) break;        f[1] = 0;        for(int i=2;i<=n;i++)        {            f[i] = (f[i-1] + k)%i;        }        printf("%d\n",(f[n-1]+m)%n + 1);    }    return 0;}

2. Hoj 1016 Joseph's problem I

Each interval is a prime number. We only need to pre-screen the prime number within a range.


 

?#include <stdio.h>  #include <stdlib.h>  #include <algorithm>  #include <string.h>  #include <math.h>  #include <iostream>  using namespace std;  #define Maxn 50000   int prime[Maxn]; int vis[Maxn]; int get_Prime(int n) {     memset(vis,0,sizeof(vis));     int np = 0;     for(int i=2;i<=n;i++)     {         if(!vis[i]) prime[np++] = i;         long long t;         for(int j=0;j<np && (t = prime[j]*i)<=n;j++)         {             vis[t] = 1;             if(i%prime[j] == 0) break;         }     } }  int f[Maxn]; int main() {     #ifndef ONLINE_JUDGE      freopen("in.txt","r",stdin);     #endif      get_Prime(Maxn);     int n;     while(scanf(" %d",&n)!=EOF && n!=0)     {         f[1] = 0;         for(int i=n-2;i>=0;i--)         {             f[n-i] = (f[n-i-1] + prime[i]) % (n - i);         }         printf("%d\n",f[n]+1);     }     return 0; } #include <stdio.h>#include <stdlib.h>#include <algorithm>#include <string.h>#include <math.h>#include <iostream>using namespace std;#define Maxn 50000int prime[Maxn];int vis[Maxn];int get_Prime(int n){    memset(vis,0,sizeof(vis));    int np = 0;    for(int i=2;i<=n;i++)    {        if(!vis[i]) prime[np++] = i;        long long t;        for(int j=0;j<np && (t = prime[j]*i)<=n;j++)        {            vis[t] = 1;            if(i%prime[j] == 0) break;        }    }}int f[Maxn];int main(){    #ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    #endif    get_Prime(Maxn);    int n;    while(scanf(" %d",&n)!=EOF && n!=0)    {        f[1] = 0;        for(int i=n-2;i>=0;i--)        {            f[n-i] = (f[n-i-1] + prime[i]) % (n - i);        }        printf("%d\n",f[n]+1);    }    return 0;}3.Hoj 1107 Joseph's problem II

K good guys and k bad guys cannot be killed each time. Ask the smallest m.

Solution: similar to array simulation. The range of start and end for each change. Each time a person is killed. The next number is 0.

include <stdio.h>  #include <stdlib.h>  #include <algorithm>  #include <string.h>  #include <math.h>  #include <iostream>  using namespace std;  #define Maxn 10100   int f[15]; bool solve(int k,int m) {     int start = 0,end = k - 1;     bool flag = true;     for(int i=2*k;i>k;i--)     {         int kill = (m-1)%i;         if(kill>=start && kill<=end)         {             flag = false;             break;         }         start = ((start - m)%i + i)%i;         end = ((end - m)%i + i)%i;     }     return flag; } void init() {     for(int k=1;k<14;k++)     {         for(int m=k+1;;m++)         {             if(solve(k,m))             {                 f[k] = m;                 break;             }         }     } } int main() {     #ifndef ONLINE_JUDGE      freopen("in.txt","r",stdin);     #endif      init();     int k;     while(scanf(" %d",&k)!=EOF && k!=0)     {         printf("%d\n",f[k]);     }     return 0; } #include <stdio.h>#include <stdlib.h>#include <algorithm>#include <string.h>#include <math.h>#include <iostream>using namespace std;#define Maxn 10100int f[15];bool solve(int k,int m){    int start = 0,end = k - 1;    bool flag = true;    for(int i=2*k;i>k;i--)    {        int kill = (m-1)%i;        if(kill>=start && kill<=end)        {            flag = false;            break;        }        start = ((start - m)%i + i)%i;        end = ((end - m)%i + i)%i;    }    return flag;}void init(){    for(int k=1;k<14;k++)    {        for(int m=k+1;;m++)        {            if(solve(k,m))            {                f[k] = m;                break;            }        }    }}int main(){    #ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    #endif    init();    int k;    while(scanf(" %d",&k)!=EOF && k!=0)    {        printf("%d\n",f[k]);    }    return 0;}   


 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.