BOJ 17822, 원판돌리기
Source: BOJ 17822 원판돌리기
문제에서 나와있는대로 구현만 할 줄 알면 풀 수 있는 그다지 어렵지 않은 문제였다
n개의 원판이 있고 각각의 원판에는 m개의 수들이 있다.
회전 시킨 후 각각의 회전마다 규칙을 따른다
총 t번 회전시킨 후 원판에 남아있는 수들의 합을 출력하면 되는 문제!
규칙 (x, d, k)
- 번호가 x배수인 원판을 d방향으로 k칸 회전 (d = 0 -> 시계방향, 1 -> 반시계방향)
- 회전 후 원판에 인접하면서 같은 수 들을 찾는다.
- 인접한 수가 있을 경우 -> 인접하면서 같은 수를 모두 지운다.
- 인접한 수가 없을 경우 -> 원판에 적힌 수의 평균을 구하고 평균보다 큰수는 -1, 작은 수는 +1
PS Logic
- temp[51]배열을 만들고 temp배열에 원판이 회전됐을 때의 배열을 담고 다시 원판(original)으로 담는다.
- 인접하면서 같은 수를 찾을 때 모듈러 연산을 통해 원판의 끝값과 처음 값이 인접하게 보일 수 있도록 장치를 만든다.
- 평균값을 구할 때 정수가 아닐 수 있으므로 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;
}
Leave a comment