BOJ 17822, 원판돌리기

Source: BOJ 17822 원판돌리기

문제에서 나와있는대로 구현만 할 줄 알면 풀 수 있는 그다지 어렵지 않은 문제였다
n개의 원판이 있고 각각의 원판에는 m개의 수들이 있다.
회전 시킨 후 각각의 회전마다 규칙을 따른다
총 t번 회전시킨 후 원판에 남아있는 수들의 합을 출력하면 되는 문제!

규칙 (x, d, k)
  1. 번호가 x배수인 원판을 d방향으로 k칸 회전 (d = 0 -> 시계방향, 1 -> 반시계방향)
  2. 회전 후 원판에 인접하면서 같은 수 들을 찾는다.
    • 인접한 수가 있을 경우 -> 인접하면서 같은 수를 모두 지운다.
    • 인접한 수가 없을 경우 -> 원판에 적힌 수의 평균을 구하고 평균보다 큰수는 -1, 작은 수는 +1

PS Logic

  1. temp[51]배열을 만들고 temp배열에 원판이 회전됐을 때의 배열을 담고 다시 원판(original)으로 담는다.
  2. 인접하면서 같은 수를 찾을 때 모듈러 연산을 통해 원판의 끝값과 처음 값이 인접하게 보일 수 있도록 장치를 만든다.
  3. 평균값을 구할 때 정수가 아닐 수 있으므로 float형으로 평균을 선언해 계산한다.
#include <bits/stdc++.h>
using namespace std;

int n, m, t;
int disk[51][51];

void solve(int x, int d, int k){
  int select = x - 1;
  if(d==1) k = -k;
  while(select<n){
    //회전 시키기
    int temp[51] = {0,};
    //temp에 회전시킨 disk 복사
    for(int i=0; i<m; i++){
      temp[(i+k+m)%m] = disk[select][i];
    }
    //disk에 temp배열 대로 값 집어넣기
    for(int i=0; i<m; i++){
      disk[select][i] = temp[i];
    }
    select += x;
  }
  //disk에 인접한 수 찾기
  bool flag = false;
  bool check[51][51] = {0,};
  int dx[4] = {0, 0, -1, 1};
  int dy[4] = {1, -1, 0, 0};
  for(int x=0; x<n; x++){
    for(int y=0; y<m; y++){
      if(disk[x][y] == -1) continue;
      for(int d=0; d<4; d++){
        int nx = x + dx[d];
        int ny = (y + dy[d] + m) % m; // 같은 원판 위에서 인접한 수를 체크하기 위한 모듈러연산
        if(nx<0 || nx>=n)continue;
        if(disk[x][y] != -1 && disk[nx][ny] != -1 && disk[x][y] == disk[nx][ny]){
          check[x][y] = true;
          check[nx][ny] = true;
          flag = true;
        }
      }
    }
  }

  if(flag){
    for(int i=0; i<n; i++){
      for(int j=0; j<m; j++){
        // if(disk[i][j] == -1) continue;
        if(check[i][j]) disk[i][j] = -1;
      }
    }
  }
  else{
    int sum = 0;
    int cnt = 0;
    for(int i=0; i<n; i++){
      for(int j=0; j<m; j++){
        if(disk[i][j] == -1) continue;
        sum += disk[i][j];
        cnt++;
      }
    }
    float avg = sum/float(cnt);
    for(int i=0; i<n; i++){
      for(int j=0; j<m; j++){
        if(disk[i][j] == -1) continue;
        if(disk[i][j] > avg) disk[i][j]--;
        else if(disk[i][j] < avg) disk[i][j]++;
      }
    }
  }
}

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin>>n>>m>>t;
  for(int i=0; i<n; i++){
    for(int j=0; j<m; j++){
      cin>>disk[i][j];
    }
  }
  while(t--){
    int x, d, k;
    cin>>x>>d>>k;
    solve(x, d, k);
  }

  int ans = 0;
  for(int i=0; i<n; i++){
    for(int j=0; j<m; j++){
      if(disk[i][j]==-1)continue;
      ans+=disk[i][j];
    }
  }
  cout<<ans;
  return 0;
}

Categories:

Updated:

Leave a comment