安全offer46を証明:サークルの最後の残りの図面(リスト、再帰的に)

1つのタイトル説明

  孤児院の子供たちを訪問するためにいくつかの小さな贈り物を準備する子供の日は毎年、牛オフは、今年も同様です。HF牛オフ、経験豊富なベテランとして、自然に我々はいくつかのゲームを用意しました。その中でも、このようなゲームがあります:まず、子どもたちは大きな円に囲まれてみましょう。彼はその後、ランダム数m、その子どもの数0のgettin番号を割り当て。M-1子どもたちが贈り物を選ぶ際に、その後の行のうちのギフトボックスのいずれかになるように歌を歌い、そして円に戻らない毎回泣い、彼の次の子から始め、0 ...メートルを続けます-1パケットの数が....に行く....最後に残った子まで、あなたが行うことができない、と珍しい「名探偵コナン」コレクターズエディションオフ牛を取得する(限定された場所をああ!! ^ _ ^)。あなたは、子どもたちが贈り物それを得るであろう、次の試してみたいですか?(注:子供の数は0からN-1である)ない子供の場合は-1を返します。

2つのアイデアや方法

  考えました

  エンドレスチェーン・ソリューションを考えてみましょう。STLは、リスト、円形のリンクリストをシミュレートするために使用。リスト自体は、スキャンチェーンの最後にイテレータが、ヘッドリストに反復子を移動させる必要があるので、いつでも、環状構造ではない場合、削除されたノードのリストは、方法を消去、原稿を失敗する反復子は、次のノードを保持する必要があります。アナログまたは円形のリンクリストを用いて、ベクター。

  2考えます:

  https://blog.csdn.net/SCS199411/article/details/92988332

  すべてのルールは、直接計算最後に残った数字を丸で囲んでデジタル分析を削除されます。n桁の暗黙的な関数f(n、m)は各時刻m番目の桁の最後の残りの図を削除。

知識ポイント:

  モジュロ演算のいくつかのプロパティを知っている必要があります、私は、例えば、かかる時間に等しい回数、5%2 = 1、および5%2%2%2 = 1をとり、2つのモジュロ演算が連想され、例えば%N - 1 =( - 1)%のN(N> 1); 3、そうでない場合は[0、N-1]の間隔xの数、明確かつ唯一の間隔の合同の数があります。例えば、X = -2、-2%N = N-2。

3 C ++コアコード

1  クラスソリューション{
 2  公共3      INT LastRemaining_Solution(INT N-、INT M)
 。4      {
 5。         // 円形のリンクリスト
 6。         // STLが悪いリストを、リストの先頭は、リストの最後に、各訪問でリダイレクトされるのみならず、
7。         INT LastRemaining_Solution(INT N-、INT M){
 8。             IF(N < 1。 || M < 1。 9。                 リターン 0 ;
 10  
11。              一覧< INT > NUMS;
 12である             ためint型 I = 0 ; iがN <; ++ I){
 13                  nums.push_back(I)。
14              }
 15  
16              リスト< 整数 > ::イテレータCUR = nums.begin()。
17              一方(nums.size()> 1 ){
 18                  のためには、int型 i = 1 ; iが<M; ++ i)が{
 19                      CUR ++ 20                      であれば(CUR == nums.end())
 21                          CUR = nums.begin()。
22                  }
23は                  リスト< INT ;> :: =イテレータ次にCUR ++    // ストレージノードに
24                  IF(==次にnums.end())
 25                      次に= nums.begin();
 26である                  cur-- ;
 27                  nums.erase (CUR);     // ノードを削除し
28                  CUR =次は;          // 次のノードを指すように
29              }
 30              リターン * ;(CUR)
 31である     }
 32 }。
コードの表示
1  クラスソリューション{
 2  公共3      INT LastRemaining_Solution(整数 nは、INTのM)
 4      {
 5          であれば(N < 1 || M < 1// 守卫代码
6              リターン - 1 7  
8          // int型の最後の= 0;
9          // ための式(I = 2 int型、iは<= N; ++ I){
 10          //    最後=(最後の+ M)%I。
11          // }
 12          // 最後に返します。
13  
14          もし(N == 1 15              リターン 0 16          リターン(LastRemaining_Solution(N- 1、M)+ M)%N。
17      }
 18 }。    
コードの表示

4 C ++完全なコード

1の#include <iostreamの>
 2の#include <ベクトル>
 3の#include <リスト>
 4  
5  使用 名前空間STDを、
6  
7  INT LastRemaining_Solution(int型のn、int型M);
8  
9  INT メイン(){
 10      COUT << LastRemaining_Solution(53)<< ENDL。
11  
12      システム(" 一時停止" )。
13      リターン 0 14  }
 15  
16  INTLastRemaining_Solution(INT N-、INT M){
 17。     IF(N < 1。 || M < 1。 リターン - 1。;
 18れている 
。19      // 円形のリンクリストをシミュレートするために使用される、ベクトル
20は      ベクトル< INT > NUM;
 21である     ためINT I = 0 ;!= N-I; Iは++ ){
 22は         num.push_back(I);
 23である     }
 24  
25      INTがスタート= 0 ;
 26は     、一方(num.size()> 1。){
27          INT cntDown = M;
 28          int型の音楽ビデオ= 開始;
 29          ながら( - cntDown){
 30              // 最後の桁にトラバースが、アレイを介して次の第1の数の場合は
31である             IF(音楽ビデオ==(num.size() - 1 )){
 32                  音楽ビデオ= 0 ;
 33である             }
 34が             {
 35本の                  ミュージックビデオ++ ;
 36              }
 37          }
 38である 
39          IF(音楽ビデオ==(num.size() - 1 )){
 40              START =0 ;
41          }
 42          {
 43              START = など;
44          }
 45          num.erase(num.begin()+ 、等)。
46      }
 47  
48      リターン NUM [ 0 ]。
49 }
コードの表示

参考資料

https://blog.csdn.net/zjwreal/article/details/88917056

https://blog.csdn.net/m0_37950361/article/details/82154753

https://blog.csdn.net/SCS199411/article/details/92988332

 

おすすめ

転載: www.cnblogs.com/wxwhnu/p/11423404.html