poj 2244 約瑟夫環

2021-07-07 01:09:34 字數 1363 閱讀 4633

這裡在推一遍公式

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

//k+1 												1

//…… ……

//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#include#include#include#include#include#include#include#include#includeusing namespace std;

#define lch(i) ((i)<<1)

#define rch(i) ((i)<<1|1)

#define sqr(i) ((i)*(i))

#define pii pair#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()

; //打表,儲存各個k值對應的m值

int k;

while(fin>>k)

{ if(!k)

break;

if(joseph[k])

{ cout<

pku2244約瑟夫環問題

題意 n個城市 標號1,2,n 輪流斷網,先停1號城市,然後每m個城市斷網,斷了的就不用計入在內了。分析 約瑟夫環殺人遊戲的乙個變種。自己總算能用之前的公式套了。我們已知的結論是 f i 表示i個人玩遊戲報m退出最後勝利者的編號,最後的結果自然是f n 遞推公式 f 1 0 f i f i 1 m ...

poj 3517 約瑟夫環。。。。。

無論是用鍊錶實現還是用陣列實現都有乙個共同點 要模擬整個遊戲過程,不僅程式寫起來比較煩,而且時間複雜度高達o nm 當n,m非常大 例如上百萬,上千萬 的時候,幾乎是沒有辦法在短時間內出結果的。我們注意到原問題僅僅是要求出最後的勝利者的序號,而不是要讀者模擬整個過程。因此如果要追求效率,就要打破常規...

POJ 1012 約瑟夫環

poj的約瑟夫環問題是原本約瑟夫環的一種變形。約瑟夫環 有n個人,從第乙個人開始報數,數到第m個人就退出,依次迴圈,最後剩下的人為勝利者。可以用迴圈鍊錶和陣列的方法做,當m,n比較小時可以一試 迴圈鍊錶,數到就刪除,數到只剩乙個就輸出 陣列,第0個位置數值置為n,其他照常 a 1 1,a 2 2.數...