Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++의 랜덤 플립 매트릭스

<시간/>

행 수가 n_rows이고 열이 n_cols인 이진 행렬이 있다고 가정합니다. 여기서 모든 값은 처음에는 0입니다. 무작위로 균일하게 0 값을 선택하고 1로 변경한 다음 해당 값의 위치 [row.id, col.id]를 반환하는 함수 flip()을 정의해야 합니다. 또한 모든 값을 다시 0으로 설정하는 또 다른 함수 reset()을 작성해야 합니다. 시스템의 Math.random() 호출 횟수를 최소화하고 시간 및 공간 복잡성을 최적화해야 합니다.

2x3 차수의 행렬이 있고 flip을 네 번 호출하면 결과는 [0,1], [1,2], [1,0], [1,1]이 됩니다.

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • 구멍이라는 지도 만들기
  • 이니셜라이저에서 다음을 수행합니다.
  • 난수 생성기 초기화, n :=행 수, m :=열 수,
  • 크기 :=n * m
  • 플립 방식에서 다음을 수행합니다. -
  • id :=난수 모드 크기, 크기를 1만큼 감소, rid :=id
  • id가 구멍에 있으면 id :=구멍[id]
  • holes[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, ]