C++のランダムフリップマトリックス
n_rowsの行数とn_colsの列数のバイナリ行列があるとします。ここでは、すべての値が最初は0です。0の値をランダムに均一に選択して1に変更し、その値の位置[row.id、col.id]を返す関数flip()を定義する必要があります。また、すべての値を0に戻す別の関数reset()を作成する必要があります。システムのMath.random()の呼び出し回数を最小限に抑え、時間とスペースの複雑さを最適化する必要があります。
次数2x3の行列があり、flipを4回呼び出すと、結果は[0,1]、[1,2]、[1,0]、[1,1]になります。
これを解決するには、次の手順に従います-
- 穴と呼ばれる地図を作成します
- 初期化子で、次の手順を実行します
- 乱数ジェネレーターの初期化、n:=行数、m:=列数、
- サイズ:=n * m
- フリップ方式では、次のようにします-
- id:=乱数modサイズ、サイズを1減らし、rid:=id
- idが穴に存在する場合、id:=hole [id]
- 穴[rid]:=穴[サイズ]の場合は穴のサイズ、それ以外の場合はサイズ
- ペアを返す(id / m、id mod m)
- リセット方法では、次のようにします
- サイズ:=n x m、穴を空ける
理解を深めるために、次の実装を見てみましょう-
例
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<int> v){
cout << "[";
for(int i = 0; i<v.size(); i++){
cout << v[i] << ", ";
}
cout << "]"<<endl;
}
class Solution {
public:
unordered_map <int, int> holes;
int n;
int m;
int size;
Solution(int n_rows, int n_cols) {
srand(time(NULL));
n = n_rows;
m = n_cols;
size = n * m;
}
vector<int> flip() {
int id = rand() % size;
size--;
int rid = id;
if(holes.count(id)){
id = holes[id];
}
holes[rid] = holes.count(size) ? holes[size] : size;
return {id / m, id % m};
}
void reset() {
size = n * m;
holes.clear();
}
};
main(){
Solution ob(2,2);
print_vector(ob.flip());
print_vector(ob.flip());
print_vector(ob.flip());
print_vector(ob.flip());
} 入力
Initialize the constructor using 2,2 and call flip four times
出力
[1, 1, ] [0, 0, ] [1, 0, ] [0, 1, ]
-
C++での行列の行方向と列方向のトラバーサル
マトリックスは2つの方法でトラバースできます。行マイズトラバーサルは、最初の行から2番目、というように最後の行まで、各行を1つずつ訪問します。行の要素は、インデックス0から最後のインデックスまで返されます。 列ごとのトラバーサルでは、要素は最初の列から最後の列に順番にトラバースされます。 2DマトリックスではM[i][j]。インデックスiは行を表すために使用され、インデックスjは列を表すために使用されます。行ごとのトラバーサルの場合は、から開始します。 i=0行目および0<=j<最後のインデックス i=1行目および0<=j<最後のインデックス ..... i=最後の行と0<=j<
-
C++での乱数生成
C++を使用して乱数を生成する方法を見てみましょう。ここでは、0からある値の範囲の乱数を生成しています。 (このプログラムでは、最大値は100です。) この操作を実行するために、srand()関数を使用しています。これはCライブラリにあります。関数voidsrand(unsigned int seed) 関数randで使用される乱数ジェネレーターをシードします。 srand()の宣言は次のようになります: void srand(unsigned int seed) シードというパラメータを取ります 。これは、疑似乱数ジェネレーターアルゴリズムによってシードとして使用される整数値です。この