거의 알고리즘 일기장

SW Expert _ 원자소멸 시뮬레이션 본문

알고리즘 문제풀이

SW Expert _ 원자소멸 시뮬레이션

건우권 2020. 10. 8. 16:34

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRFInKex8DFAUo

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

풀이방법

간단하게만 설명하자면

1. board를 [4001][4001]로 확장시킨다. 왜냐하면 0.5움직일때 부닥치는 경우도 있기때문에

2. 좌표를 (주어지는 좌표)*2 + 2000 로 재계산해서 저장

3. 원자들을 움직인다. 이때 좌표값이 0<= 좌표값 <=4000 이 넘으면 그 원자는 무시한다.

4. board에 움직인 원자들의 에너지 값들을 추가한다.

5. 충돌여부를 확인한다. 충돌시에는 에너지값 추가, 아닐때는 뭐 그냥 넘어감


주의사항

1. 충돌여부를 판단할때 board를 초기화 시켜주어서 board를 재사용한다. (사실 이게 제일 중요함)

2. 원자를 움직일때마다 board를 탐색하는 불상사를 없애기 위해서 vector나 배열에 원자들의 상태를 저장해놓는다.


코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>

using namespace std;

class Atomic
{
public:
	int y;
	int x;
	int dir;
	int k;

	Atomic(int y_in = 0, int x_in = 0, int dir_in = 0, int k_in = 0)
		:y(y_in), x(x_in), dir(dir_in), k(k_in){}
};

//상하좌우순
int dy[4] = { 1, -1, 0, 0 };
int dx[4] = { 0, 0, -1, 1 };
int N;
int board[4001][4001];
Atomic atomics[1000];

bool IsInRange(int y, int x)
{
	if (y >= 0 && y <= 4000 && x >= 0 && x <= 4000)
		return true;
	return false;
}

void MoveAtomics()
{
	for (int i = 0; i < N; i++)
	{
		Atomic& atomic = atomics[i];
		int ny = atomic.y + dy[atomic.dir];
		int nx = atomic.x + dx[atomic.dir];

		//범위 밖이면, atomic.k를 0으로 만들어서 계산하지 말자
		if (IsInRange(ny, nx) == false || atomic.k == 0)
		{
			atomic.k = 0;
			continue;
		}

		atomic.y = ny;
		atomic.x = nx;
	}
}

int GetEnergy()
{
	int energy = 0;

	//board에 에너지 넣기
	for (int i = 0; i < N; i++)
	{
		Atomic atomic = atomics[i];
		board[atomic.y][atomic.x] += atomic.k;
	}

	//정산
	for (int i = 0; i < N; i++)
	{
		Atomic& atomic = atomics[i];
		
		if (atomic.k == 0)
			continue;

		//충돌 안했을시
		if (board[atomic.y][atomic.x] == atomic.k)
		{
			board[atomic.y][atomic.x] = 0;
		}

		//충돌시 에너지를 0으로 만들어 주자
		else
		{
			atomic.k = 0;
			energy += board[atomic.y][atomic.x];
			board[atomic.y][atomic.x] = 0;
		}
	}
	return energy;
}

void solve()
{
	int answer = 0;

	//Input
	cin >> N;
	int x, y, dir, k;
	for (int i = 0; i < N; i++)
	{
		cin >> x >> y >> dir >> k;
		x = x * 2 + 2000;
		y = y * 2 + 2000;

		Atomic atomic(y, x, dir, k);
		atomics[i] = atomic;
	}

	//4001번돌렸는데 안되면 안되는겨
	for (int i = 0; i < 4001; i++)
	{
		//move
		MoveAtomics();

		//정산
		answer += GetEnergy();
	}

	cout << answer << '\n';
}

int main()
{
	int testcase;
	cin >> testcase;
	for (int i = 0; i < testcase; i++)
	{
		cout << "#" << i + 1 << " ";
		solve();
	}
	return 0;
}

다른 블로그를 좀 참고해서 풀었다.ㅎ

반응형
Comments