본문 바로가기

code/BOJ

d

#include <iostream>
#include <vector>
using namespace std;
int T, N;
int vst[2001][2001];	// 초기화 완료
vector<int> cls[1001];	// 초기화 완료
int ans;	// 초기화 완료
struct info{
	int r, c, d, k;
};
vector<info> atom;
#define IN(r, c) (0 <= (r) && (r) <= 2001 && 0 <= (c) && (c) <= 2001)
int dr[] = { 1, -1, 0, 0 };
int dc[] = { 0, 0, -1, 1 };
int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> T;
	for (int tc = 1; tc <= T; ++tc) {
		cin >> N;
		while (N--) {
			int r, c, d, k; cin >> r >> c >> d >> k;
			atom.push_back({ r + 1000, c + 1000, d, k });
		}

		ans = 0;
		int c = 0;
		while(1) {
			bool proc = false;
			for (int cc = 1; cc < c; ++cc)
				cls[cc].clear();
			c = 1;
			for(int a = 0; a < atom.size(); ++a){
				// 처리 대상 아니면 continue;
				if (atom[a].r == -1) continue;

				// 이동
				atom[a].r += dr[atom[a].d];
				atom[a].c += dc[atom[a].d];
				if (!IN(atom[a].r, atom[a].c)) {
					atom[a].r = -1; continue;
				}

				proc = true;

				// 방문 처리
				if (vst[atom[a].r][atom[a].c] == 0) {	// 미방문
					vst[atom[a].r][atom[a].c] = c;	// 방문
					cls[c].push_back(a);
					c++;
				}
				else {	// 기방문
					cls[vst[atom[a].r][atom[a].c]].push_back(a);
				}
				
			}
			if (proc == false) break;
			else
				for (int a = 0; a < atom.size(); ++a) {
					// 처리 대상 아니면 continue;
					if (atom[a].r == -1) continue;
					if (vst[atom[a].r][atom[a].c]) {	// 원자 있음
						if (cls[vst[atom[a].r][atom[a].c]].size() > 1) {	// 폭발 대상 있음
							int rr = atom[a].r, cc = atom[a].c;
							for (auto at : cls[vst[atom[a].r][atom[a].c]]) {
								vst[atom[at].r][atom[at].c] = 0;
								atom[at].r = -1;	// 제거
								ans += atom[at].k;	// 점수 더하기
							}
							cls[vst[rr][cc]].empty();	// 폭발 대상 처리 완료 -> 제외
							vst[rr][cc] = 0;
						}
					}
				}
		}
		cout << '#' << tc << ' ' << ans << '\n';
	}

	return 0;
}