[모의 SW 역량테스트] 원자 소멸 시뮬레이션
본문 바로가기
알고리즘 모음집/알고리즘 (Algorithm)

[모의 SW 역량테스트] 원자 소멸 시뮬레이션

by KyeongMin 2019. 12. 20.
728x90
반응형

 

#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>	
using namespace std;
int ret;
int dy[] = { 1,-1,0,0 };
int dx[] = { 0,0,-1,1 };
struct Data {
	int y, x, dir, k;
};
bool cmp(Data a, Data b) {
	if (a.y == b.y)return a.x < b.x;
	return a.y < b.y;
}
vector<Data>v;
bool safeRange(int idx) {
	if (v[idx].y < -2000 || v[idx].y>2000 || v[idx].x < -2000 || v[idx].x>2000)return true;
	else return false;
}
void move() {
	for (int i = 0; i < v.size(); i++){
		v[i].y += dy[v[i].dir]; v[i].x += dx[v[i].dir];
		if(safeRange(i)){
			v.erase(v.begin() + i);
			i--;
		}
		//범위 넘었을때 지워주기 함수 짜기
	} 
}
void touchChk() {
	sort(v.begin(), v.end(),cmp);
	for (int i = 0; i < v.size(); i++) {
		int sum = v[i].k; int flag = 0;
		for (int j = i + 1; j < v.size(); j++) {
			if (!(v[i].y == v[j].y&&v[i].x == v[j].x))break;
			sum += v[j].k;//에너지 생성 저장
			v.erase(v.begin()+j);//원자 소멸
			j--;
			flag = 1;
		}
		if (flag) { ret += sum; v.erase(v.begin() + i); i--; }//부딪친 원자 지우기
	}
}
void playEnergy() {
	while (v.size() != 0) {
		move();//원자 이동
		touchChk();//원자 소멸 확인
	}
}
void init() {
	ret = 0;
	v.clear();
	int x, y, dir, k;
	int N;
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> x >> y >> dir >> k;
		v.push_back({ y * 2,x * 2,dir,k });
	}
	playEnergy();
}
int main(void) {
	int T;
	cin >> T;
	for (int tc = 1; tc <= T; tc++) {
		init();
		cout << '#' << tc << " " << ret << endl;
	}
	return 0;
}

단순하게 생각하면 쉽지만 아이디어가 필요한것 같다 우선 맵을 그려서 각 배열에 절대 못담기 때문에 담는다고 해도

시간초과가 나서 그냥 벡터를 이용해서 그 벡터에 담긴것만 사용해서 중복되는 좌표에 있는것은 사라지게 하고

범위를 넘는것 최대 -2000 ~2000을 갈때 까지 갔다면 왠만해서 무한적으로 이제 에너지가 생산이 되지 않는것

 

여기서는 1.5 즉 0.5초에 대해서도 부딪히는게 있기 때문에 x,y 좌표를 2배로 늘려서 해결하는방법과

주어진 조건에 맞추어 코딩하는것이 중요했습니다. 처음에 제가 실패를 받았는데 

그이유가 정렬을 해주고 중복된 좌표에 대해서 덧셈을 진행해야했는데 그러지 않아서 틀리는 결과를 받았습니다.

이점은 정말 해서는 않되는 실수고 진짜 실제시험때 이러면 난감하신거 아시죠?

항상 실수를 줄이는게 답입니다. 무튼 오늘 여기까지이고 여러분들도 즐거운 알고리즘 되세요.

728x90
반응형

댓글