ジョセフの円形単独リンクリストの問題

参考ここのブログます。https://blog.csdn.net/u011500062/article/details/72855826 

ジョセフの問題
ジョセフの問題は、よく知られた問題である:Nの個人サークル、1 Countinから最初の人は、Mが殺されると報告し、その後始まる新聞から次の人。だから、もう一度、最後の残りの一つは、最終的な勝者を求めています。
たとえば、唯一の3人は、それらを呼び出す、Bは、C、彼らは円を形成、2人が死亡が報告されたと仮定し、Aからオフ数えるようになりました。

最初のスタートはオフカウント、彼は1を報告しました。幸いにも脱出しました。
そして、Bの数を報告左折、彼は2を報告しました。非常に悲惨な、彼は殺された
Cをしてから1からのgettin数は
その後、新聞の数を回し、彼は2を報告しました。また、それが殺されました。
最終勝者Cのある
ソリューション
一般的な解決策
2をノードにだけデータ構造を学び、私たちはこのプロセスをシミュレートするために、リストの方法を使用することができる、N Nリンクリストのノードとして見られ、個人、ノード1ポイント、ノード2つのノード3ポイント、... ...、ノードNにN-1のノード点は、ノードN 1とノード点は、このように環を形成します。初めから1、2、3 ......ノードオフ番号ダウンすると、すべてのレポートMは、そのノードがリングから削除されて置きます。次いで、1つのスタートパケットから次のノード番号。最終リスト残りのノード。それは究極の勝者です。

短所:
nは、短時間で非常に大きな(例えば、何百万、数千万)、ほとんどの方法の結果をmがないときにO(nm)と、の時間計算まで、ゲームの全過程をシミュレートします。

式メソッド
ヨセフスは、古典的な数学の問題であり、我々は簡単に報告された順番にこの番号を見つけることができ、パターンがあるようです。輸出再帰を容易にするために、我々はどのようなトピックを再定義します。
問題:Nレポート番号が続く個人番号1,2、......、N、すべてのレポートMは、数字の最後の勝者を見つけ、その人を殺します。

ここでは最初に結論を投げました。後、あなたがこの式のステップを理解来て何ですバイステップで取ります。
再帰式:
F(N、M)=(F(1-N、M)+ M)%N
F(N、M)=(F(1-N、M)+ M)%N
F(N、 M)F(N、M)はすべての人のレポートMを殺すために、個々のパケットのNの数を表し、最終的な勝者数
F(N-1、M) F(N-1、M)は、 N-1を表し、パーソナルデジタル新聞、すべての人M報告を殺す、数字の最後の勝者
たち以下は、すべての人への手紙を持っていますが、数字ではありません。
1,2,3,4,5,6,7,8,9,10,11
1,2,3,4,5,6,7,8,9,10,11

11人を表し、彼らが最初に殺された人のレポートにつき3と仮定すると、並んで。
人々の数は3に殺される最初は、最初のものは数1で、彼は最初のラウンドからオフ数えるようになりました。
第4号は、再び1から始まる人々の数は、この時間は、私たちはこの1つは、第4のチームヘッドであると言うことができることを報告しました。第二ラウンドは6を殺される人の数です。
人々の7数は、再び私たちはこの1つは第7チームのヘッドであると言うことができ、この時間をオフにカウントし始めました。第三ラウンドは9を殺した人の数です。
......
9ラウンド、第2の男が再びオフカウントし始めたとき、この時間は、私たちはこの1つは、数2チームのヘッドであると言うことができます。これは、8人が死亡しているラウンド数です。
人または数2の次の人は、彼が1から始まる番号が、残念ながら彼はこのラウンドで殺されたことを報告しました。
最後の勝者は人々 7の数です。
次の図は、このプロセスを示しています。

今、私たちは、漸化式が得られる方法を見て!
アレイは、この式を記載したように、上記の表の各行は、次のとおりです。このラウンドで生存インデックス位置

F(1,3):一人だけ、その人が勝者であり、彼は位置が0で添字
F(2,3)=(F(1、3)+3)%2%2 = 3 = 1F (2,3)=(F(1,3 )+3)%2 = 3%2 = 1: 二人の個人が存在する場合、勝者は、位置インデックスである。
F(3,3)=(F( 2,3)+3)%3 = 4 %3 = 1fを(3,3)=(F(2,3)+3)%3 = 4%3 = 1: 3がある個人、勝者位置インデックス。1
F(4,3)=(F(3,3)+3)%= 4 4 4%= 0F(4,3)=(F(3,3)+3)= 4 4% %4 = 0:そこに4人があり、下付き位置勝者は0です
......
F(11,3)= 6F(11,3)= 6
素晴らしいこと!今、あなたはまだこの式それの妥当性を疑いますか?上記の例では、実際にこの再帰式は、添字勝者を計算できることを示し、次のようにこの式を導出する方法を説明します。
質問1:6の添字位置の勝者、我々はすでに11人を知っていると仮定します。、添字位置の勝者はどのくらいの10人の次のラウンドであるときに?
:添字6によって彼の位置が3になるように、実際に、人々は3王Qianmianを移動した後、第3の男の最初のラウンドを削除し、この勝利はまた、前方3を移動しました。

質問2:3の添字位置の勝者、我々はすでに10人を知っていると仮定します。、添字位置の勝者はどのくらいの11人の次のラウンドであるときに?
:これは間違っている可能性があり、F(10,3 =(11,3)は、fので、前の質問の逆で、我々はすべて、バック3を移動 )+ 3F(11,3)= F(10,3)を3。しかし、現在の数に金型の最終的な数ので、(11,3)、F =(F、範囲外の配列が存在し得る (10,3)は+3)%の11F(11,3)=(F(10,3)+ 3)11%は
質問3:彼らは人を殺すために、Mを報告したときに数が今、Nを読み込むように変更、その配列はどのように移動するのですか?
:各々の次の人が前進Mビットの配列に相当する頭であると、人を殺します。N-1は、既知の個体、ビット勝者添字F(N-1、M)である場合 、F(N-1、M)、 N個の個々は、それが可能であるように、(Mへ後退させます配列境界、ヘッド部分が受信される上、型べきN)、双方のF(N、M)=( F(N-1、M)+ M)%のNF(N、M)=(F( N-1、M)+ M )を%n
注:インデックス位置の注目が勝者になってきていることをどのように再帰的なコアを理解しています。それぞれが人を殺し、実際には、Mビットのこの配列を前方に移動させることです。そして、あなたはこの再帰式を得ることができ、オーバー逆転。

計算された結果が配列添字であるため、最終的な数字は1を追加する必要があります

以下を達成するためのJavaコード:

パブリック   ノードjosephusKill(ノードヘッド、int型M){
 場合(ヘッド== NULL || head.next ==ヘッド|| M <1 ){
 戻りヘッド。
} 
ノードCUR = head.next。
int型 TMP = 1 ;
しばらく(!CUR = ヘッド){ 
TMP ++ ; 
CUR = cur.next。
} 
TMP = getLive(TMP、M)。
一方、(!= 0 --tmp {)
ヘッド = head.nextと、
} 
head.next = ヘッド。
リターンヘッド; 
}

公共 INT getlive(整数 nは、INTのM){
 場合(N == 1 ){
 返す 1 
} 
戻り(getlive(INT N-1、INTの M)+ M)%N。

}

 




おすすめ

転載: www.cnblogs.com/doufuyu/p/11069701.html