https://www.acmicpc.net/problem/14890
각각의 행과 열에대해서 인덱스가 증가하는 방향으로 한 번, 감소하는 방향으로 두 번 탐색을 진행하면서 예외 처리를 해주었다.
같은 높이가 몇개가 연속되는지 찾아서, 입력으로 주어지는 L과 비교하는 것이 관건인데, 1 1 2 2 이런식으로 증가하는 값에 대한 것은 그 개수를 파악하기 쉽지만, 2 2 1 1 이런식의 수열을 왼쪽에서 순서대로 탐색하면, 번거롭기 때문에 그냥 뒤에서부터도 연속되는 개수를 새서 경우를 따졌다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | /* cnt == n이면 경로 확정 루프시작 인덱스로 다시 돌아오면 가능 확정 차이가 2이상이면 경로 불가능 확정 cnt < len 인데 증가하면 불가능 확정 경사로 설치한 곳에 또 설치하려고 하면 불가능 확정 */ #include<iostream> using namespace std; int n, len, m[102][102], Rchk[102], Cchk[102]; bool vis[102][102]; int main(void) { cin >> n >> len; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) cin >> m[i][j]; for (int i = 0; i < n; i++) { int cnt = 1; for (int j = 1; j < n ; j++) { //col 증가 if (m[i][j] == m[i][j - 1]) cnt++; //cnt == len이면 확정 -> chk = 1로 else if (m[i][j] - m[i][j - 1] >= 2) { Rchk[i] = -1; break; } else if (m[i][j] > m[i][j - 1] && cnt < len) { Rchk[i] = -1; break; } else if (m[i][j] - m[i][j - 1] == 1 && cnt >= len) { for (int k = j - 1; k >= j - len; k--) { vis[i][k] = true; } cnt = 1; } else if (m[i][j] < m[i][j - 1]) cnt = 1; } if (cnt == n) { Rchk[i] = 1; continue; } //col 감소 if (Rchk[i] == -1 || Rchk[i] == 1) continue; //이미 위에서 확정 했으면 스킵 cnt = 1; for (int j = n - 2; j >= 0; j--) { bool endFlag = false; if (m[i][j] == m[i][j + 1]) cnt++; else if (m[i][j] - m[i][j + 1] >= 2) { Rchk[i] = -1; break; } else if (m[i][j] > m[i][j + 1] && cnt < len) { Rchk[i] = -1; break; } else if (m[i][j] - m[i][j + 1] == 1 && cnt >= len) { for (int k = j + 1; k <= j + len; k++) { if (vis[i][k]) {//설치한 곳에 또 설치하려고 하는 경우 Rchk[i] = -1; endFlag = true; break; } else vis[i][k] = true; } if (endFlag) break; cnt = 1; } else if (m[i][j] < m[i][j + 1]) cnt = 1; if (j == 0) Rchk[i] = 1; } } //경사로 놨던거 초기화 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) vis[i][j] = false; } for (int i = 0; i < n; i++) { int cnt = 1; for (int j = 1; j < n; j++) { //col 증가 if (m[j][i] == m[j-1][i]) cnt++; //cnt == len이면 확정 -> chk = 1로 else if (m[j][i] - m[j-1][i] >= 2) { Cchk[i] = -1; break; } else if (m[j][i] > m[j-1][i] && cnt < len) { Cchk[i] = -1; break; } else if (m[j][i] - m[j-1][i] == 1 && cnt >= len) { for (int k = j - 1; k >= j - len; k--) { vis[k][i] = true; } cnt = 1; } else if (m[j][i] < m[j-1][i]) cnt = 1; } if (cnt == n) { Cchk[i] = 1; continue; } //col 감소 if (Cchk[i] == -1 || Cchk[i] == 1) continue; //이미 위에서 확정 했으면 스킵 cnt = 1; for (int j = n - 2; j >= 0; j--) { bool endFlag = false; if (m[j][i] == m[j+1][i]) cnt++; else if (m[j][i] - m[j+1][i] >= 2) { Cchk[i] = -1; break; } else if (m[j][i] > m[j+1][i] && cnt < len) { Cchk[i] = -1; break; } else if (m[j][i] - m[j+1][i] == 1 && cnt >= len) { for (int k = j + 1; k <= j + len; k++) { if (vis[k][i]) {//설치한 곳에 또 설치하려고 하는 경우 Cchk[i] = -1; endFlag = true; break; } else vis[k][i] = true; } if (endFlag) break; cnt = 1; } else if (m[j][i] < m[j+1][i]) cnt = 1; if (j == 0) Cchk[i] = 1; } } int res = 0; for (int i = 0; i < n; i++) { if (Rchk[i] == 1) res++; if (Cchk[i] == 1) res++; } cout << res; return 0; } | cs |
'알고리즘 문제 풀이 > 백준 온라인 저지' 카테고리의 다른 글
백준 17069번: 파이프 옮기기 2 (C++) (0) | 2019.08.09 |
---|---|
백준 17070번: 파이프 옮기기 1 (C++) (0) | 2019.08.09 |
백준 14889번: 스타트와 링크 (C++) (0) | 2019.08.07 |
백준 14891번: 톱니바퀴 (C++) (0) | 2019.08.07 |
백준 15683번: 감시 (C++) (0) | 2019.08.07 |