Search
Duplicate

십자가 찾기

주차
16
문제번호
16924
언어
C++
티어
실버
유형
구현
nj_Blog
nj_상태
이해도
풀이
사람
이해도 2
13 more properties

Memo

로직 설명

설명 하기 전에..
"사용할 수 있는 십자가의 개수는 N×M이하이어야 한다."
십자가 최소 크기는 3 X 3 이므로 가장 작은 십자가 하나 만으로도 격자판을 만들 수 있음.
따라서 이 문제의 키 포인트는 십자가를 못만드는 경우를 찾는 것.
로직
맵 전체를 돌면서 * 을 만나면, 그것이 십자가의 중심인 것으로 생각하고 상하좌우를 조사해 나갑니다.
이때 십자가를 만드는 경우 방문처리를 해줍니다.
출력 부분에서 방문처리가 안된 부분이 '*' 인 경우에 -1을 출력합니다.

코드 설명

void the_cross(int y, int x, int length)
C++
복사
십자가의 시작 위치부터 시작하여 상하좌우의 길이를 늘려가며 만들 수 있는 모든 십자가를 구합니다.

어려웠던 부분

문제 이해하기... ㅠㅠ

Code

제출 날짜

@4/13/2021

메모리

6772 KB

시간

40 ms
#include <iostream> #include <vector> #define endl "\n" int N, M; char g_map[101][101]; bool cross_check[101][101]; int dy[4] = {0, 0, 1, -1}; int dx[4] = {1, -1, 0, 0}; std::vector<std::pair<std::pair<int, int>, int> > cross; int ans; void input_faster() { std::ios_base::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); } void the_cross(int y, int x, int length) { int ny, nx; for (int i = 0 ; i < 4 ; ++i) { ny = y + length * dy[i]; nx = x + length * dx[i]; //만일 하나라도 십자가의 성질을 만족하지 않으면 return; if (ny <= 0 || ny > N || nx <= 0 || nx > M || g_map[ny][nx] != '*' || g_map[ny][nx] != '*') return ; } // 네 방향 모두 만족하면, 방문처리를 해줌. (여기는 십자가가 만들어 졌다는 뜻) // 위에서 체크해 주지 않은 이유는, 하나라도 만족하지 못하면 십자가는 만들어 지지 않기 때문. return 하기 전에 방문처리를 해제해 주는 방법도 있음. for (int i = 0 ; i < 4 ; ++i) { ny = y + length * dy[i]; nx = x + length * dx[i]; cross_check[ny][nx] = 1; } cross_check[y][x] = 1; cross.push_back({{y, x}, length}); the_cross(y, x, length + 1); } void input() { input_faster(); std::cin >> N >> M; for (int i = 1 ; i <= N ; ++i) for (int j = 1 ; j <= M ; ++j) std::cin >> g_map[i][j]; } void make_the_cross() { for (int i = 1 ; i <= N ; ++i) for (int j = 1 ; j <= M ; ++j) if (g_map[i][j] == '*') the_cross(i, j, 1); } void solve() { make_the_cross(); } void print_val() { for (int i = 1 ; i <= N ; ++i) for (int j = 1; j <= M; ++j) { // 만약 *이 있는데 십자가가 만들어지지 않았다면, -1 출력 if (g_map[i][j] == '*' && !cross_check[i][j]) { std::cout << -1; return ; } } std::cout << cross.size() << endl; for (auto& i : cross) std::cout << i.first.first << " " << i.first.second << " " << i.second << endl; } int main() { input(); solve(); print_val(); return (0); }
C++
복사