728x90
반응형
https://www.acmicpc.net/problem/17822
17822번: 원판 돌리기
반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 각각의 원판에는 M개의 정수가 적혀있고, i번째 원판에 적힌 j번째 수의 위치는 (i, j)로 표현한다. 수의 위치는 다음을 만족한다. (i, 1)은 (i, 2), (i, M)과 인접하다. (i, M)은 (i, M-1), (i, 1)과 인접하다. (i, j)는 (i, j-1), (i, j+1)과 인접하다. (2 ≤ j ≤ M-1) (1, j)는 (
www.acmicpc.net
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define NS 52
#define MS 52
int N, M, T;
int num[NS][MS];
int xi, di, ki;
int chk[NS][MS];
int dy[] = { 0,1,0,-1 };
int dx[] = { 1,0,-1,0 };
int flag;// 나중에 지워진적 없는지 있는지 파악하기위해
int flag1;
int ret;
void sumNum() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
ret += num[i][j];
}
}
}
void dfs(int y, int x, int sameNum) {
for (int dir = 0; dir < 4; dir++) {
int ny = y + dy[dir]; int nx = x + dx[dir];
if (ny <= 0||ny>N)continue;
if (nx <= 0)nx = M;
if (nx > M)nx = 1;
if (chk[ny][nx] == 0 && num[ny][nx] == sameNum && num[ny][nx] != 0) {
chk[ny][nx] = 1;
num[ny][nx] = 0;
flag = 1;
dfs(ny, nx, sameNum);
}
}
}
void searchNum() {
flag1 = 0;
memset(chk, 0, sizeof(chk));
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
if (chk[i][j] == 0 && num[i][j] != 0) {
flag = 0;
chk[i][j] = 1;
dfs(i, j, num[i][j]);
if (flag == 1) {//한개라도 중복되서 지웠으면
num[i][j] = 0;
flag1 = 1;
}
}
}
}
}
void rightClock(int y) {//0 시계방향
int snum = num[y][M];
for (int x = M - 1; x >= 1; x--) {
num[y][x + 1] = num[y][x];
}
num[y][1] = snum;//끝값 저장
}
void leftClock(int y) {//1 반시게 방향
int sum = num[y][1];
for (int x = 2; x <= M; x++) {
num[y][x - 1] = num[y][x];
}
num[y][M] = sum;
}
void calNum(int sum, int cnt) {
float a = (float)sum / cnt;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
if (num[i][j] != 0 && num[i][j] < a) {
num[i][j]++;
}
else if (num[i][j] != 0 && num[i][j] > a) {
num[i][j]--;
}
}
}
}
void rotCir() {//원판 돌리기 시뮬
for (int t = 0; t < T; t++) {
scanf("%d %d %d", &xi, &di, &ki);
for (int i = 1; i <= N; i++) {// 너무 너무한 치명적 실수M으로 해서 틀렸었음
if (i % xi == 0) {//xi의 배수이면
if (di == 0) {
for (int k = 0; k < ki; k++) {
rightClock(i);
}
}
else if (di == 1) {
for (int k = 0; k < ki; k++) {
leftClock(i);
}
}
}
}
searchNum();
if (flag1 == 0) {
int sum = 0;
int cnt = 0;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
sum += num[i][j];
if (num[i][j] != 0) {
cnt++;
}
}
}
//sum = sum / cnt;//평균값
if (cnt != 0)
calNum(sum, cnt);
}
}
}
void init() {
scanf("%d %d %d", &N, &M, &T);
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
scanf("%d", &num[i][j]);
}
}
rotCir();
sumNum();
}
int main(void) {
init();
cout << ret << endl;
return 0;
}
흠 이문제는 진짜 쉬운데 포인트를 하나 말하자면 배열은 직선이고 여기서 원하는 것은 원이기때문에
직선인 배열을 원같이쓰기만 한다면 쉽게 풀리는 문제입니다. 물론 실수를 좀 범해서 좀 걸렸지만 초보자들도 쉽게
풀만한 문제 같습니다. 그럼 오늘은 너무 피곤해서 여기까지..
728x90
반응형
'알고리즘 모음집 > 알고리즘 (Algorithm)' 카테고리의 다른 글
SW Expert Academy - [모의 SW 역량테스트] 보호 필름 (0) | 2019.11.14 |
---|---|
백준 17779 게리맨더링2 (0) | 2019.11.13 |
알고리즘 카카오 - 비밀지도, 캐시, 프렌즈4블록 (0) | 2019.11.08 |
백준 10798 세로읽기, 백준 11728 배열합치기 (0) | 2019.11.07 |
백준 2146 다리 만들기 (0) | 2019.10.13 |
댓글