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)
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 }