C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で整数をパワー値の順に並べ替えてk番目の要素を求める方法

整数xの「パワー」とは、次の手順を繰り返してxを1へ変換するまでに必要なステップ数として定義されます。

  • xが偶数の場合:x = x / 2
  • xが奇数の場合:x = 3 * x + 1

例えば、x = 3のパワーは7です。これは、3が1になるまでに7ステップかかるためです(3 → 10 → 5 → 16 → 8 → 4 → 2 → 1)。なお、この変換手順は「コラッツ予想」として知られる数列に関連しており、任意の正の整数は必ず1に到達すると予想されています。

ここで、整数lo、hi、kが与えられたとします。区間[lo, hi]内のすべての整数をパワー値の昇順にソートし、パワー値が同じ場合は整数そのものの昇順で並べ替えます。そのうえで、ソート後のk番目の整数を求めるのがこの問題です。

具体例

入力がlo = 12、hi = 15、k = 2の場合、出力は13になります。各数値のパワーは以下の通りです。

  • 12のパワー:9
  • 13のパワー:9
  • 14のパワー:17
  • 15のパワー:17

したがって、ソート後の順序は[12, 13, 14, 15]となり、k = 2番目の要素は13です。

解法のアプローチ

この問題を解くには、以下の手順に従います。

  • 引数nを受け取るgetTurnメソッドを定義します。
  • ret := 0 で初期化します。
  • nが1になるまでループします。
    • nが奇数ならn := n * 3 + 1、偶数ならn := n / 2とします。
    • retを1ずつ増やします。
  • メインメソッドでは、iをloからhiまでループします。
    • (getTurn(i), i)というペアを作成します。
    • 作成したペアをretに挿入します。
  • ペアをパワー値の昇順でソートします。パワー値が等しい場合は整数値の昇順で並べます。
  • ret[k - 1]の2番目の値(元の整数)を返します。

C++での実装例

理解を深めるために、以下の実装例を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    vector < pair <int, int> > ret;
    static bool cmp(pair <int, int>& a, pair <int, int>& b){
        return a.first == b.first ? a.second < b.second : a.first < b.first;
    }
    int getTurn(int n){
        int ret = 0;
        while(n != 1){
            if(n & 1){
                n = n * 3 + 1;
            }
            else n >>= 1;
            ret ++;
        }
        return ret;
    }
    int getKth(int lo, int hi, int k) {
        for(int i = lo; i <= hi; i++){
            pair <int, int> temp;
            temp.first = getTurn(i);
            temp.second = i;
            ret.push_back(temp);
        }
        sort(ret.begin(), ret.end(), cmp);
        return ret[k - 1].second;
    }
};
main(){
    Solution ob;
    cout << (ob.getKth(12, 15, 2));
}

入力

12
15
2

出力

13
  1. C++で解く「Maze III」:ボールを最短距離で穴に落とすアルゴリズム

    問題の概要 空きスペースと壁からなる迷路の中に、ボールが1つ置かれています。ボールは空きスペース上を上(u)・下(d)・左(l)・右(r)のいずれかの方向に転がって移動できますが、壁にぶつかるまで停止しません。ボールが停止した時点で、次の方向を選択できます。また、迷路内には穴(hole)が1つあり、ボールが穴の位置まで転がると、その穴に落ちます。 ボールの初期位置・穴の位置・迷路の情報が与えられたとき、ボールを最短距離で穴に落とすための移動手順を求めます。ここでいう距離とは、スタート地点(含まない)から穴(含む)までにボールが通過した空きスペースの数として定義されます。 移動方向は「u」「d

  2. C++でシェーカーソートを実装する方法|アルゴリズムとサンプルコード解説

    シェーカーソートとは シェーカーソート(Shaker Sort)は、与えられたデータを昇順に並べ替えるためのソートアルゴリズムの一つです。バブルソートとよく似ていますが、決定的に異なるのは配列を双方向(往復)に走査して整列を進める点です。「カクテルソート」「双方向バブルソート」と呼ばれることもあります。このアルゴリズムの最悪計算量は O(n²) です。 アルゴリズムの手順 開始   ShakerSort() 関数は、引数としてデータ配列 arr と要素数 n を受け取る。   // ネストした for ループを使ってソートを実装する。   外側のループは i を 0 から n-1 まで回し、