본문 바로가기
알고리즘

BOJ 20165 - 인내의 도미노 장인 호석(C++)

by 장중앙 2021. 10. 28.

https://www.acmicpc.net/problem/20165

 

20165번: 인내의 도미노 장인 호석

사람을 화나게 하는 법은 다양하다. 그 중에서도 악질은 바로 열심히 세워놓은 도미노를 넘어뜨리는 것이다. 이번에 출시된 보드 게임인 "너 죽고 나 살자 게임"은 바로 이 점을 이용해서 2명이

www.acmicpc.net

 

풀이

라운드만큼 반복, 한 라운드에 공격과 수비 순으로 동작

원래 상태 복구를 위해 원본 배열 보관 originp[][]

라운드가 지속되면서 변경되는 배열 map[][]을 갱신하며 진행

1. 공격

  1-1. y, x, dir이 주어짐, cnt=map[y][x]-1, res=1 

  1-2. cnt가 0보다 큰 동안 반복

  1-3. dir에 따라 y, x값 변경(한 칸 이동) -> y, x값이 범위 밖으로 나가면 break

  1-4. map[y][x]이 0이 아니면 res++

  1-5. map[y][x]가 cnt보다 크면 cnt=map[y][x] (새로운 기준(cnt)으로 넘어뜨리는 것이 더 많이 넘어 뜨림)

        작으면 cnt--

  1-6. map[y][x]=0으로 넘어졌다는 표시 갱신

 

2. 수비

  2-1. y, x값이 주어짐

  2-2. map[y][x] 값이 0이라면 원래 값(origin[y][x])로 되돌리고

        그 외에는 넘어지지 않았다는 의미이므로 그대로 유지 

 

3. 라운드 만큼 진행되었으면 map[][]을 확인

    map[][]=0이면 F, 이외의 값이 있다면 S 출력

 

#include <iostream>

using namespace std;
	
int N, M, R;
int origin[101][101];
int map[101][101];
int dy[] = { 0,0,1,-1 };
int dx[] = { 1,-1,0,0 };

int direction(char c) {
	if (c == 'E')
		return 0;
	else if (c == 'W')
		return 1;
	else if (c == 'S')
		return 2;
	else
		return 3;
}

int attack(int y, int x, int d) {
	int cnt = map[y][x]-1;
	if (cnt < 0)return 0;

	int res = 1;
	map[y][x] = 0;
	while (cnt > 0 ) {
		y = y + dy[d];
		x = x + dx[d];
		if (y < 1 || y > N || x < 1 || x > M)break;
		if(map[y][x]!=0)
			res += 1;
		if (map[y][x] > cnt)
			cnt = map[y][x]-1;
		else
			cnt -= 1;
		map[y][x] = 0;
	}
	return res;
}

void defence(int y, int x) {
	if (map[y][x] == 0) {
		map[y][x] = origin[y][x];
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int score = 0;
	cin >> N >> M >> R;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			cin >> origin[i][j];
			map[i][j] = origin[i][j];
		}
	}

	for (int i = 0; i < R; i++) {
		int attack_y, attack_x, defence_y, defence_x;
		char dir;
		cin >> attack_y >> attack_x >> dir;
		int d = direction(dir);
		score+=attack(attack_y, attack_x, d);
		cin >> defence_y >> defence_x;
		defence(defence_y, defence_x);
	}
    
	cout << score << endl;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
            // 원본과 비교
			if (origin[i][j] == map[i][j]) {
				cout << "S ";
			}
			else {
				cout << "F ";
			}
		}
		cout << endl;
	}

	return 0;
}

댓글