ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PS] 코드트리: 싸움땅
    문제해결 2023. 10. 25. 17:24

    싸움땅

     

    memset(PMAP, -1, sizeof(int) * 20 * 20);

    이걸

    memset(PMAP, -1, 20 * 20);

    이렇게 써버려서 자꾸 오답처리됐다.
    애먼 알고리즘만 자꾸 검토하다가 시간을 얼마나 날렸는지...

     

    #include <bits/stdc++.h>
    using namespace std;
    
    #define pii pair<int, int>
    #define endl "\n"
    #define FOR(i, N) for (int i = 0; i < int(N); i++)
    #define iib(r, c) (0 <= r && r < N && 0 <= c && c < N)
    
    struct Player {
    	pii pos;
    	int dir, str, atk = 0, pt = 0;
    	int stat() { return str + atk; }
    	Player(int r, int c, int d, int s) { pos = make_pair(r, c), dir = d, str = s; }
    };
    vector<Player> vp;
    
    int dr[4] = { -1, +0, +1, +0 };
    int dc[4] = { +0, +1, +0, -1 };
    
    int N, M, K;
    int PMAP[20][20];
    priority_queue<int, vector<int>, less<int>> GMAP[20][20];
    
    int main() {
    	cin >> N >> M >> K;
    	FOR(i, N) FOR(j, N) {
    		int atk; cin >> atk;
    		GMAP[i][j].push(atk);
    	}
    
    	memset(PMAP, -1, sizeof(int) * 20 * 20);
    	FOR(i, M) {
    		int x, y, d, s; cin >> x >> y >> d >> s; x -= 1, y -= 1;
    		vp.emplace_back(x, y, d, s);
    		PMAP[x][y] = i;
    	}
    
    	FOR(cnt, K) {
    		FOR(i, M) {
    			// 1. 한칸씩 이동
    			int r, c, didx = vp[i].dir; tie(r, c) = vp[i].pos;
    			int nr = r + dr[didx], nc = c + dc[didx];
    			if (!iib(nr, nc)) {
    				didx = vp[i].dir = (vp[i].dir + 2) % 4;
    				nr = r + dr[didx], nc = c + dc[didx];
    			}
    			PMAP[r][c] = -1;
    
    			// 2-1. 이동한 곳에 플레이어가 없다면,
    			if (PMAP[nr][nc] == -1) {
    				// 가지고 있는 총을 놓고 가장 쎈 총을 가져온다.
    				GMAP[nr][nc].push(vp[i].atk);
    				vp[i].atk = GMAP[nr][nc].top(); GMAP[nr][nc].pop();
    
    				// 이 땅에 내가 있노라 선언
    				PMAP[nr][nc] = i;
    				vp[i].pos = make_pair(nr, nc);
    			}
    			// 2-2. 이동한 곳에 플레이어가 있다면,
    			else {
    				int opp_idx = PMAP[nr][nc];
    				int win_idx = (vp[i].stat() == vp[opp_idx].stat() ?
    					(vp[i].str > vp[opp_idx].str ? i : opp_idx) : (vp[i].stat() > vp[opp_idx].stat()) ? i : opp_idx);
    				int lose_idx = (i + opp_idx) - win_idx;
    				int win_stat = vp[win_idx].stat(), lose_stat = vp[lose_idx].stat();
    
    				// 진 놈의 경우
    				// 총을 내려둠
    				GMAP[nr][nc].push(vp[lose_idx].atk);
    				vp[lose_idx].atk = 0;
    				// 원래방향으로 1칸 전진, 안되면 오른쪽으로 90도 회전하며
    				FOR(_, 4) {
    					int ldidx = (_ + vp[lose_idx].dir) % 4;
    					int nnr = nr + dr[ldidx], nnc = nc + dc[ldidx];
    					if (iib(nnr, nnc) && PMAP[nnr][nnc] == -1) {
    						// 여기로 이주하고
    						PMAP[nnr][nnc] = lose_idx;
    						vp[lose_idx].dir = ldidx;
    						vp[lose_idx].pos = make_pair(nnr, nnc);
    						// 가장 쌘 총 주워가기
                            GMAP[nnr][nnc].push(0);
    						vp[lose_idx].atk = GMAP[nnr][nnc].top(); GMAP[nnr][nnc].pop();
    						break;
    					}
    				}
    
    				// 이긴 놈의 경우 점수 획득하고
    				vp[win_idx].pt += (win_stat - lose_stat);
    				// 이주하기
    				PMAP[nr][nc] = win_idx;
    				vp[win_idx].pos = make_pair(nr, nc);
    				// 가장 쎈 총 줍줍
    				GMAP[nr][nc].push(vp[win_idx].atk);
    				vp[win_idx].atk = GMAP[nr][nc].top(); GMAP[nr][nc].pop();
    			}
    		}
    	}
    
    	FOR(i, M) cout << vp[i].pt << " "; cout << endl;
    }
Designed by Tistory.