hdu 3089 (快速约瑟夫环)

Josephus again

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 741    Accepted Submission(s): 210


Problem Description
In our Jesephus game, we start with n people numbered 1 to n around a circle, and we eliminated every k remaining person until only one survives. For example, here's the starting configuration for n = 10, k = 2, The elimination order is 2, 4, 6, 8, 10, 3, 7, 1, 9. So 5 survives.The problem: determine the survivor's number , J(n, k).
 

 

Input
There are multiple cases, end with EOF
each case have two integer, n, k. (1<= n <= 10^12, 1 <= k <= 1000)
 

 

Output
each case a line J(n, k)
 

 

Sample Input
10 2 10 3
 

 

Sample Output
5 4
 

 

Source
 

 

Recommend
lcy
 

 1 //约瑟夫环递推式 报到k出列 那么我们需要for(i:1~n) f[i]=(f[i-1]+k)%i。f[1]=0; 其中 编号是0~n-1 
 2 //当f[i]+k>=i 就常规递推,否则快速跳跃,跳跃长度为(i-f[i])/(k-1),利用i和k的增长速度差算长度。
 3 //因为编号是0~n-1,所以最后答案要+1和数组下标对应。
 4 #include<bits/stdc++.h>
 5 #define clr(x) memset(x,0,sizeof(x))
 6 #define clr_1(x) memset(x,-1,sizeof(x))
 7 #define mod 1000000007
 8 #define LL long long
 9 #define INF 0x3f3f3f3f
10 #define mp make_pair
11 #define pb push_back
12 #define mp make_pair
13 #define fi first
14 #define se second
15 using namespace std;
16 const int N=5e5+10;
17 LL n,k,t;
18 LL solve(LL n,LL k)
19 {
20     LL ans=0,i;
21     if(k==1) return n;
22     for(i=2;i<=n;)
23     {
24         if(ans+k>=i)
25             ans=(ans+k)%i,i++;
26         else
27         {
28           t=min((i-1-ans)/(k-1),n-(i-1));
29           i+=t-1;
30           ans+=k*t;
31           ans%=i;
32           i++;
33         }
34     }
35     return ans%n+1;
36 }
37 int main()
38 {
39     while(scanf("%lld%lld",&n,&k)!=EOF)
40     {
41         printf("%lld\n",solve(n,k));
42     }
43     return 0;
44 }
View Code

 

posted @ 2018-05-13 15:34  hk_lin  阅读(168)  评论(0编辑  收藏  举报