Problem Solving/BOJ(백준)

[BOJ]백준 20056번: 마법사 상어와 파이어볼

이진2 2020. 10. 19. 20:20

www.acmicpc.net/problem/20056

 

20056번: 마법사 상어와 파이어볼

첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치�

www.acmicpc.net

정말 애증의..... 문제 .......... 

일단 풀이부터 올린다

#include <cstdio>
#include <vector>
using namespace std;
typedef struct { int r, c; }point;
typedef struct { int w, s, d; }cosm;
vector<cosm> map[51][51];
vector<cosm> tmp[51][51];
int n, m, k,ans, dc[] = { 0,1,1,1,0,-1,-1,-1 }, dr[] = { -1,-1,0,1,1,1,0,-1 };
point move(point cur, cosm c) {
	point next;
	next.r = cur.r + dr[c.d] * c.s;
	next.c = cur.c + dc[c.d] * c.s;
	next.r = (next.r + n*1001) % n;
	next.c = (next.c + n*1001) % n;
	return next;
}
int main() {
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; i++) {
		int r, c, w, s, d;
		scanf("%d%d%d%d%d", &r, &c, &w, &s, &d);
		map[r-1][c-1].push_back({ w,s,d });
	}
	while (k--) {
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				if (!map[i][j].empty()) {
					for (auto x : map[i][j]) {
						point next = move({ i,j }, x);
						tmp[next.r][next.c].push_back(x);
					}
					map[i][j].clear();
				}
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				if (!tmp[i][j].empty()) {
					if (tmp[i][j].size() == 1) {
						map[i][j].push_back(tmp[i][j][0]);
						tmp[i][j].pop_back();
						continue;
					}
					int num=tmp[i][j].size(),weight = 0, speed = 0, dir= tmp[i][j][0].d % 2, nd=0;
					for (auto x : tmp[i][j]) {
						weight += x.w; speed += x.s;
						if ((x.d % 2) != dir)nd = 1;
					}
					tmp[i][j].clear();
					if (weight < 5)continue;
					weight = weight / 5; speed = speed / num;

					for(int l=0;l<8;l++)
						if ((l % 2) == nd) {
							map[i][j].push_back({ weight,speed,l });
						}
				}
	}
	for (int i = 0; i < n; i++)for (int j = 0; j < n; j++) {
		while (!map[i][j].empty()) {
			ans += map[i][j].back().w;
			map[i][j].pop_back();
		}
	}
	printf("%d", ans);
	return 0;
}