https://www.acmicpc.net/problem/14890
[필자 사고]
구현 문제이다.
총 4가지의 경우의 수를 판단해야 된다.
1. 가로 행이 모두가 높이가 같을때
2. 가로 행 높이차가 2이상일 때
3. 오른쪽방향으로 경사가 질 때
4. 왼쪽 방향으로 경사가 질 때
1,2 번을 먼저 코드로 작성하여 1번과 2번 case 가 아닌경우 즉 3,4번만 판단하게 코드를 작성했다.
[문제 풀이]
경사로 설치 가능성 확인 함수들
- isDifTwo: 연속된 두 칸의 높이 차이가 2 이상인 경우를 확인합니다.
- isAllSame: 모든 칸의 높이가 같은 경우를 확인합니다.
- leftRight: 왼쪽에서 오른쪽으로 경사진 경우
bool isDifTwo(vector<vector<int>>& map, int sero) {
for (int i = 0; i < N - 1; i++) {
int dif = map[sero][i] - map[sero][i + 1];
if (abs(dif) >= 2) return true;
}
return false;
}
bool isAllSame(vector<vector<int>>& map, int sero) {
for (int i = 0; i < N - 1; i++) {
if (map[sero][i] != map[sero][i + 1]) return false;
}
resultCount++;
return true;
}
int leftRight(vector<vector<int>>& map, int sero, int garo) {
int beforeLoad = 1;
if (beforeLoad == L) {
return garo;
}
if (garo == N - 1) return -1;
for (int i = garo; i < N - 1; i++) {
if (map[sero][i] == map[sero][i + 1]) {
beforeLoad++;
} else {
return -1;
}
if (beforeLoad == L) {
return i + 1;
}
}
return -1;
}
경사로 설치 함수
지형을 순회하며 경사로 설치가 가능한지 확인하고, 가능하면 resultCount를 증가시킵니다.
void makeGame(vector<vector<int>>& map) {
for (int i = 0; i < N; i++) {
if (isAllSame(map, i)) continue;
if (isDifTwo(map, i)) continue;
bool flag = true;
int beforeLoad = 1;
for (int k = 0; k < N - 1; k++) {
if (map[i][k] == map[i][k + 1]) {
beforeLoad++;
continue;
}
if (map[i][k] > map[i][k + 1]) {
int load = leftRight(map, i, k + 1);
if (load == -1) {
flag = false;
break;
}
k = load - 1;
beforeLoad = 0;
continue;
}
if (map[i][k] < map[i][k + 1]) {
if (beforeLoad < L) {
flag = false;
break;
}
beforeLoad = 1;
continue;
}
}
if (flag) resultCount++;
}
}
[전체 코드]
#include <iostream>
#include <vector>
#include <cstring>
#include <cmath>
using namespace std;
//경사가 오른쪽으로 내려가있다면 0 위로 1 왼쪽 2 아래는 3
int N, L;
int resultCount = 0;
vector<vector<int>> arr;
vector<vector<int>> arr2;
void Input() {
cin >> N >> L;
arr.resize(N);
for (int i = 0; i < N; i++) {
arr[i].resize(N);
}
arr2 = arr;
for (int i = 0; i < N; i++) {
for (int k = 0; k < N; k++) {
cin >> arr[i][k];
arr2[k][i] = arr[i][k];
}
}
}
bool isDifTwo(vector<vector<int>>& map, int sero) {
for (int i = 0; i < N - 1; i++) {
int dif = map[sero][i] - map[sero][i + 1];
if (abs(dif) >= 2)return true;
}
return false;
}
bool isAllSame(vector<vector<int>> &map,int sero) {
for (int i = 0; i < N - 1; i++) {
if (map[sero][i] != map[sero][i + 1])return false;
}
resultCount++;
return true;
}
int leftRight(vector<vector<int>>& map, int sero, int garo) {
int beforeLoad = 1;
if (beforeLoad == L) {
return garo;
}
if (garo == N - 1)return -1;
for (int i = garo; i < N-1; i++) {
if (map[sero][i] == map[sero][i + 1]) {
beforeLoad++;
}
else {
return -1;
}
if (beforeLoad == L) {
return i+1;
}
}
return -1;
}
void makeGame(vector<vector<int>>& map) {
for (int i = 0; i < N; i++) {
if (isAllSame(map, i) == true)continue;
if (isDifTwo(map, i) == true) continue;
bool flag = true;
int beforeLoad = 1;
for (int k = 0; k < N-1; k++) {
if (map[i][k] == map[i][k + 1]) {
beforeLoad++;
continue;
}
if (map[i][k] > map[i][k + 1]) {
int load = leftRight(map, i, k+1);
if (load == -1) {
flag = false;
break;
}
k = load-1;
beforeLoad = 0;
continue;
}
if (map[i][k] < map[i][k + 1]) {
if (beforeLoad < L) {
flag = false;
break;
}
beforeLoad = 1;
continue;
}
}
if (flag == true) resultCount++;
}
}
void Print(vector<vector<int>>& map) {
for (int i = 0; i < N; i++) {
for (int k = 0; k < N; k++) {
cout << map[i][k] << " ";
}
cout << "\n";
}
}
int main(void) {
Input();
makeGame(arr);
makeGame(arr2);
cout << resultCount;
}
'백준 > 삼성기출문제' 카테고리의 다른 글
백준 14500 c++ "테트로미노" -PlusUltraCode- (1) | 2024.10.05 |
---|---|
백준 c++ 14499 "주사위 굴리기" -PlusUltraCode- (1) | 2024.07.05 |
백준 c++ 23288 "주사위 굴리기2" -PlusUltraCode- (0) | 2024.06.28 |
백준 17144 c++ "미세먼지 안녕!" -PlusUltraCode- (0) | 2024.06.26 |
백준 c++ 19236 "청소년 상어" -PlusUltraCode- (0) | 2024.06.24 |