UVA - 1452 Jump (約瑟夫環變式)
阿新 • • 發佈:2018-12-01
題目大意:
給出n,m,約瑟夫環共n項,每數到m殺一個人,問剩下的倒數第3個人、倒數第2個人、倒數第1個人的編號分別是多少
題解:
因為我們都知道求約瑟夫環問題是f[1]=0, f[n]=(f[n-1]+k)%i ,所以一開始我的想法是就用同樣的方法來推倒數第2個人,
f[2]=0,f[n]=(f[n-1]+k)%i ;但是得出的結果卻不對,
在倒數第2局標號為1的不一定在本局出局,在m=2的情況下是這樣,被樣例誤導了........
但是倒數第2局一定是隻有編號為0和1的兩個人,所以我們可以求出倒數第1個人在倒數第2局的標號,然後1-這個編號倒數第2個人在倒數第2局的編號,有了起始編號之後剩下的就是按照那個公式推了( f[n]=(f[n-1]+k)%i)
同理,倒數第3個人在倒數第3局的編號,然後順著退就ok了。於是我們可以求出倒數第1個和倒數第2個人在倒數第3局的編號,它們和倒數第3個人的編號一定分別是0,1,2,所以ans3=(0^1^2)^ans1^ans2;
#include<bits/stdc++.h> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #define max_n 10010 typedef long long LL; using namespace std; int main() { //freopen("input.txt","r",stdin); int n,k,T; scanf("%d",&T); int ans1=0,ans2=0,ans3=0; while(T--) { scanf("%d%d",&n,&k); ans1=0,ans2=0,ans3=0; for(int i=2;i<=n;++i) { ans1=(ans1+k)%i; if(i==2) { ans2=1-ans1; continue; } ans2=(ans2+k)%i; if(i==3) { ans3=(0^1^2)^ans1^ans2; continue; } ans3=(ans3+k)%i; } printf("%d %d %d\n",ans3+1,ans2+1,ans1+1); } return 0; }