poj 2244 約瑟夫環

這裏在推一遍公式

由於每次都是由1開始,所以可以把1排除掉,直接將城市數變成k-1,把2當作1.

假設上一輪選中k=ANS[I-1],那麼剩下的從k+1開始:

<p><pre name="code" class="cpp">//k+1 												1
//……											<span style="white-space:pre">	</span>……
//n												n-k
//n+1 (就是原來的1)										n-k+1
//……												……
//k+n-2 											n-1
//本輪X 											下一輪X‘




但是本輪只剩下n-1個數了,而編號還是從1~n(中間缺少了ANS[i-1]),中斷了,而下一輪是連續的

所以重新排序成1~n-1,否則從下一輪轉換回本輪數字對不上

下一輪轉本輪     X = X’+K = X'+ANS[i-1]

再重新得出順序  a =  (X-2)%(n-1)+1 這樣原來本輪的編號就由1、2、……ANS[i-1]-1、ANS[I-1]+1、……n 變成1~n-1

合起來a = (X'+ANS[I-1]-2)%(N-1)+1。

如果知道下一輪選中的數在下一輪中的位置X',那麼就可以知道該數在本輪的位置a

X’ = (m-1)%(n-1)+1

而這個a就是ANS[I],如果ANS[I]==1,就是選中的城市Ulm,m不符合

#include<iostream>  
#include<map>
#include<string>   
#include<algorithm>  
#include<fstream>
#include<cmath>  
#include<vector>
#include<queue>
#include<map>
#include<math.h>
using namespace std;  
#define lch(i) ((i)<<1)  
#define rch(i) ((i)<<1|1)  
#define sqr(i) ((i)*(i))  
#define pii pair<int,int>  
#define mp make_pair  
#define FOR(i,b,e) for(int i=b;i<=e;i++)  
#define FORE(i,b,e) for(int i=b;i>=e;i--)  
#define ms(a)   memset(a,0,sizeof(a))  
const int maxnum =21252;
const  int  mod = 10007;
int n;

//
//#define _DEBUG_
int main()    
{  
#ifdef _DEBUG_
	fstream fin("G:/1.txt");
#else
#define fin cin
#endif
	int Joseph[150]={0};  //打表,保存各個k值對應的m值  
  
    int k;  
    while(fin>>k)  
    {  
        if(!k)  
            break;  
  
        if(Joseph[k])  
        {  
            cout<<Joseph[k]<<endl;  
            continue;  
        }  
  
        
        int ans[150]={0};  //第i輪殺掉 對應當前輪的編號爲ans[i]的人  
                          //PS:每一輪都以報數爲“1”的人開始重新編號  
		n=k-1;
        int m=1;    //所求的最少的報數  
		int flag = 2;
        for(int i=1;i<n;i++)  //殺n-1次都不是1就可以了 
        {  
			if(!ans[i-1])
				ans[i]=(m-1)%(n-i+1)+1;
			else
	            ans[i]=(ans[i-1]+m-2)%(n-i+1)+1;   //n-i爲剩餘的人數  
			if(ans[i]==1){//殺掉了1
				i=0;
				m++;
			}
        }  
        Joseph[k]=m;  
        cout<<m<<endl;  
    }  
    return 0;  
} 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章