본문 바로가기
알고리즘/[ADV] 삼성 SW 역량 테스트 A형

[코드트리] 시공의 돌풍 (삼성 SW 역량테스트 2019 상반기 오전 1번)

by 피로물든딸기 2024. 6. 8.
반응형

삼성 A형 전체 링크

 

https://www.codetree.ai/training-field/frequent-problems/problems/heros-of-storm

이후 설명 및 입/출력은 링크 참고

 

시공의 돌풍 문제 풀이BOJ 17144 : 미세먼지 안녕! 과 같다.

#include <stdio.h>

#define MAX (50 + 10)

int T;
int R, C, time;
int MAP[MAX][MAX];

typedef struct st
{
	int r;
	int c;
}RC;

RC tornado[2];
int tcnt;

void input()
{
	scanf("%d %d %d", &R, &C, &time);

	tcnt = 0;
	for (int r = 1; r <= R; r++)
	{
		for (int c = 1; c <= C; c++)
		{
			scanf("%d", &MAP[r][c]);

			if (MAP[r][c] == -1)
			{
				tornado[tcnt].r = r;
				tornado[tcnt++].c = c;
			}
		}
	}
}

void output()
{
	for (int r = 1; r <= R; r++)
	{
		for (int c = 1; c <= C; c++)
			printf("%d ", MAP[r][c]);
		putchar('\n');
	}
}

/* 순서대로 왼쪽, 위, 오른쪽, 아래 */
int dr[] = { 0,-1,0,1 };
int dc[] = { -1,0,1,0 };

void diffusion()
{
	int tmpMAP[MAX][MAX];

	for (int r = 1; r <= R; r++)
		for (int c = 1; c <= C; c++)
			tmpMAP[r][c] = 0;

	for (int r = 1; r <= R; r++)
	{
		for (int c = 1; c <= C; c++)
		{
			if (MAP[r][c] > 0)
			{
				int cnt, dust;

				cnt = dust = 0;
				for (int i = 0; i < 4; i++)
				{
					int nr, nc;

					nr = r + dr[i];
					nc = c + dc[i];

					if (nr < 1 || nc < 1 || nr > R || nc > C) continue;
					if (MAP[nr][nc] == -1) continue;

					dust = MAP[r][c] / 5;

					tmpMAP[nr][nc] += dust;
					cnt++;
				}

				MAP[r][c] -= dust * cnt;
			}
		}
	}

	for (int r = 1; r <= R; r++)
		for (int c = 1; c <= C; c++)
			if (tmpMAP[r][c]) MAP[r][c] += tmpMAP[r][c];
}

void move()
{
	int up_r = tornado[0].r;
	int down_r = tornado[1].r;

	/* (1, 1) ~ (up_r , C)의 반시계 */
	for (int r = up_r - 1; r > 1; r--) MAP[r][1] = MAP[r - 1][1];
	for (int c = 1; c <= C - 1; c++) MAP[1][c] = MAP[1][c + 1];
	for (int r = 1; r <= up_r - 1; r++) MAP[r][C] = MAP[r + 1][C];
	for (int c = C; c > 1; c--) MAP[up_r][c] = MAP[up_r][c - 1];

	MAP[up_r][2] = 0;

	/* (down_r, 1) ~ (R, C)의 시계 */
	for (int r = down_r + 1; r <= R - 1; r++) MAP[r][1] = MAP[r + 1][1];
	for (int c = 1; c <= C - 1; c++) MAP[R][c] = MAP[R][c + 1];
	for (int r = R; r > down_r; r--) MAP[r][C] = MAP[r - 1][C];
	for (int c = C; c > 1; c--) MAP[down_r][c] = MAP[down_r][c - 1];

	MAP[down_r][2] = 0;
}

int main(void)
{
	// scanf("%d", &T);
	T = 1;
	for (int tc = 1; tc <= T; tc++)
	{
		input();

		for (int t = 0; t < time; t++)
		{
			diffusion();
			move();
		}

		int count = 0;
		for (int r = 1; r <= R; r++)
			for (int c = 1; c <= C; c++)
				if (MAP[r][c] != -1) count += MAP[r][c];

		printf("%d\n", count);
	}

	return 0;
}
반응형

댓글