ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코드트리 48] 싸움땅
    C 프로그래밍/CODE TREE 삼성 기출 복원 2022. 11. 1. 13:07
    728x90

    https://www.codetree.ai/frequent-problems/battle-ground/description

     

    코드트리

    국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.

    www.codetree.ai

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cmath>
    int N, M, K;
    
    struct COMP
    {
    	bool operator()(const int &a, const int &b)
    	{
    		return a < b;	// 큰거 부터 
    	}
    };
    
    
    std::priority_queue<int, std::vector<int>, COMP> GUN[20 + 2][20 + 2];
    int POS[20 + 2][20 + 2];
    
    struct _st
    {
    	int x, y;
    	int d;
    	int s;
    	int g;
    }Players[30 + 2];
    
    int score[30 + 2];
    
    
    // dir 
    // 0상 1우 2하 3좌
    int dir_x[4] = { -1, 0, 1, 0 };
    int dir_y[4] = { 0, 1, 0, -1 };
    int dir_op[4] = { 2, 3, 0, 1 };
    
    
    
    void input()
    {
    	scanf("%d %d %d", &N, &M, &K);
    	for (int r = 1; r <= N; r++) {
    		for (int c = 1; c <= N; c++) {
    			int power = 0;
    			scanf("%d", &power);
    			if (power != 0) GUN[r][c].push(power);
    		}
    	}
    	for (int i = 1; i <= M; i++) {
    		// 위치, 방향, 초기능력치
    		scanf("%d %d %d %d", &Players[i].x, &Players[i].y, &Players[i].d, &Players[i].s);
    		POS[Players[i].x][Players[i].y] = i;
    	}
    }
    
    
    int fight(int p1, int p2)
    {
    	int p1_total = Players[p1].s + Players[p1].g;
    	int p2_total = Players[p2].s + Players[p2].g;
    
    	if (p1_total > p2_total) return p1;
    	else if (p1_total < p2_total) return p2;
    	else if (p1_total == p2_total) {
    		if (Players[p1].s > Players[p2].s) return p1;
    		else if (Players[p1].s < Players[p2].s) return p2;
    	}
    	return -1;
    }
    
    
    void move_loser(int num)
    {
    	int x = Players[num].x;
    	int y = Players[num].y;
    	if (Players[num].g != 0) {
    		GUN[x][y].push(Players[num].g);
    		Players[num].g = 0;
    	}
    
    	int dir = Players[num].d;
    
    	for (int p = dir; p < (dir + 4); p++) {
    		p %= 4;	// 방향이 3보다 커지면 안된다 
    		int nx = x + dir_x[p];
    		int ny = y + dir_y[p];
    
    		if (nx < 1 || nx > N || ny < 1 || ny > N || POS[nx][ny]) continue;
    		if (POS[nx][ny] == 0) {
    			if (!GUN[nx][ny].empty()) {
    				Players[num].g = GUN[nx][ny].top();
    				GUN[nx][ny].pop();
    			}
    			Players[num].x = nx;
    			Players[num].y = ny;
    			Players[num].d = p;
    			POS[nx][ny] = num;
    			break;
    		}
    	}
    }
    
    
    
    
    void move_players()
    {
    	for (int i = 1; i <= M; i++) {
    		int x = Players[i].x; 
    		int y = Players[i].y;
    		POS[x][y] = 0;	// 겹쳐 있지 않음 싸워서 이동하기 때문
    
    		// 이동
    		int p = Players[i].d;
    		int nx = x + dir_x[p];
    		int ny = y + dir_y[p];
    
    		if (nx < 1 || nx > N || ny < 1 || ny > N) {
    			p = dir_op[p];
    			nx = x + dir_x[p];
    			ny = y + dir_y[p];
    		}
    		// 갱신
    		Players[i].x = nx;
    		Players[i].y = ny;
    		Players[i].d = p;
    
    		// 해당 칸에 다른 플레이어가 없다면 
    		if (POS[nx][ny] == 0) {
    			POS[nx][ny] = i;		// 위치시킴 
    			if (!GUN[nx][ny].empty()) {
    				if (Players[i].g == 0) {
    					Players[i].g = GUN[nx][ny].top();
    					GUN[nx][ny].pop();
    				}
    				else {
    					GUN[nx][ny].push(Players[i].g);
    					Players[i].g = GUN[nx][ny].top();
    					GUN[nx][ny].pop();
    				}
    			}
    		}
    		// 해당 칸에 다른 플레이어가 있다면 
    		else {
    			int comp = POS[nx][ny];
    			POS[nx][ny] = 0;			// 누가 이길지 모르니까 일단 삭제
    			int win = fight(comp, i);
    			int lose = (win == i) ? comp : i;
    
    			POS[nx][ny] = win;			// 이긴사람 위치시킴
    
    			int add = abs((Players[win].s + Players[win].g) - (Players[lose].s + Players[lose].g));
    			score[win] += add;
    
    
    			// 진 플레이어
    			move_loser(lose);
    
    			// 이긴 플레이어
    			// 해당 격자 공간이 비어있을 수 도 있다는점
    			// 이거 신경 써줘야 한다. 
    			if (!GUN[nx][ny].empty()) {
    				if (Players[win].g != 0) GUN[nx][ny].push(Players[win].g);
    				Players[win].g = GUN[nx][ny].top();
    				GUN[nx][ny].pop();
    			}
    			// 해당 칸에 총 없으면 그냥 자기꺼 가져간다.
    		}
    	}
    }
    
    
    
    
    void simulation()
    {
    	for (int turn = 1; turn <= K; turn++) {
    		move_players();
    	}
    }
    
    
    
    void output()
    {
    	for (int i = 1; i <= M; i++) {
    		printf("%d ", score[i]);
    	}
    	printf("\n");
    }
    
    int main()
    {
    	input();
    	simulation();
    	output();
    	return 0;
    }
    728x90

    댓글

Designed by Tistory.