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

[코드트리] 원자 충돌 (삼성 SW 역량테스트 2020 하반기 오전 2번)

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

삼성 A형 전체 링크

 

https://www.codetree.ai/training-field/frequent-problems/problems/atom-collision

 

원자 충돌 문제 풀이BOJ 20056 : 마법사 상어와 파이어볼과 같다.

#include <stdio.h>

#define MAX (50 + 5)

int T;
int N, M, K;

typedef struct st1
{
	int r;
	int c;
	int m;
	int s;
	int d;
}ATOM;

ATOM atom[10000 + 5000];
int acnt;

int dr[] = { -1, -1, 0, 1, 1, 1, 0, -1 };
int dc[] = { 0, 1, 1, 1, 0, -1, -1, -1 };

typedef struct st2
{
	int m;
	int s;
	int d;
	int odd;
	int even;
	int count;
}INFO;

void input()
{
	scanf("%d %d %d", &N, &M, &K);

	acnt = 0;
	for (int i = 0; i < M; i++)
	{
		scanf("%d %d %d %d %d", &atom[acnt].r, &atom[acnt].c, &atom[acnt].m, &atom[acnt].s, &atom[acnt].d);
		acnt++;
	}
}

void simulate()
{
	for (int i = 0; i < K; i++)
	{
		/* atom의 이동 */

		INFO MAP[MAX][MAX] = { 0 };

		for (int f = 0; f < acnt; f++)
		{
			int nr, nc;

			nr = atom[f].r + dr[atom[f].d] * (atom[f].s % N); /* speed가 N보다 클 수 있다. */
			nc = atom[f].c + dc[atom[f].d] * (atom[f].s % N);

			if (nr > N) nr -= N;
			if (nc > N) nc -= N;
			if (nr < 1) nr += N;
			if (nc < 1) nc += N;

			MAP[nr][nc].m += atom[f].m;
			MAP[nr][nc].s += atom[f].s;
			MAP[nr][nc].d = atom[f].d; /* atom이 1개인 경우만 유효 */

			if (atom[f].d & 1) MAP[nr][nc].odd++;
			else MAP[nr][nc].even++;

			MAP[nr][nc].count++;
		}

		/* MAP을 보고 atom을 다시 생성 */

		acnt = 0;

		for (int r = 1; r <= N; r++)
		{
			for (int c = 1; c <= N; c++)
			{
				if (MAP[r][c].count == 0) continue;

				if (MAP[r][c].count == 1)
				{
					atom[acnt].r = r;
					atom[acnt].c = c;
					atom[acnt].m = MAP[r][c].m;
					atom[acnt].s = MAP[r][c].s;
					atom[acnt].d = MAP[r][c].d;
					acnt++;

					continue;
				}

				if (MAP[r][c].m / 5 == 0) continue;

				int dir[4] = { 0 };
				if (MAP[r][c].odd == MAP[r][c].count || MAP[r][c].even == MAP[r][c].count)
					dir[0] = 0, dir[1] = 2, dir[2] = 4, dir[3] = 6;
				else
					dir[0] = 1, dir[1] = 3, dir[2] = 5, dir[3] = 7;

				for (int f = 0; f < 4; f++)
				{
					atom[acnt].r = r;
					atom[acnt].c = c;
					atom[acnt].m = MAP[r][c].m / 5;
					atom[acnt].s = MAP[r][c].s / MAP[r][c].count;
					atom[acnt].d = dir[f];
					acnt++;
				}
			}
		}
	}
}

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

		simulate();

		int sum = 0;
		for (int f = 0; f < acnt; f++) sum += atom[f].m;

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

	return 0;
}
반응형

댓글