용꿀
꼬마개발자허니
용꿀
전체 방문자
오늘
어제
  • 분류 전체보기 (247)
    • 개발 (74)
      • 스프링 입문 (7)
      • 스프링 기본 (9)
      • ToDo List using JPA (2)
      • 스프링 개념 (9)
      • 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 (8)
      • 스프링 MVC (3)
      • CS (18)
      • 개발 팁 (8)
      • 스프링 MSA (5)
      • 곰터뷰🐻 (5)
    • 알고리즘 (169)
      • 알고리즘 문제 풀이 (165)
    • 잡동사니 (1)
      • 노래 가사 (1)
hELLO · Designed By 정상우.
용꿀

꼬마개발자허니

(C++) 백준 18808번 - 스티커 붙이기
알고리즘/알고리즘 문제 풀이

(C++) 백준 18808번 - 스티커 붙이기

2023. 4. 30. 03:32

문제 링크 : https://www.acmicpc.net/problem/18808

 

18808번: 스티커 붙이기

혜윤이는 최근에 다양한 대회를 참여하면서 노트북에 붙일 수 있는 스티커들을 많이 받았다. 스티커는 아래와 같이 사각 모눈종이 위에 인쇄되어 있으며, 스티커의 각 칸은 상하좌우로 모두 연

www.acmicpc.net

풀이

모든 경우를 고려하여 풀이를 진행해야 하는 브루트포스 문제이다.

스티커를 회전하는 것을 구현하는 방법을 생각하는 것과 스티커를 붙일 수 있는 경우를 판별하는 방법을 구현하는 것이 매우 어려웠다.

또한 checknput() 메서드의 이중 for문 뒤에 위치한 제일 마지막 경우를 체크하기 위한 코드를 생각하지 못해 상당히 헤매었다.

#include <iostream>

using namespace std;

int laptop[42][42];
int sticker[12][12], tmp[12][12];
int n, m, k, r, c, cnt;
bool isput;

void validate(int i, int j){ // 스티커를 붙일 수 있는지 판별
    for(int k = 0; k < r; k++){
        for(int l = 0; l < c; l++){
            if(laptop[i+k][j+l] == 1 && sticker[k][l] == 1) return; // 스티커끼리 겹치는 부분이 있다면 붙이는 것이 불가능
        }
    }
    // 붙이기가 가능할 경우에는 laptop에 반영
    for(int k = 0; k < r; k++){
        for(int l = 0; l < c; l++){
            if(sticker[k][l] == 1){
                laptop[i+k][j+l] = 1;
            } 
        }
    }
    isput = true; // 붙였음을 표시
}

bool checknput(){ // 스티커를 붙일 수 있다면 laptop에 반영하고 true를 아니라면 false를 반환
    isput = false; // 스티커를 붙일 수 있는지 여부
    if(n-r < 0 || m-c < 0) return false;
    for(int i = 0; i <= n-r; i++){
        for(int j = 0; j <= m-c; j++){
            if(isput) return true; // 스티커를 붙일 수 있었다면 true를 반환
            validate(i, j); // 스티커를 붙일 수 있을지 판별하고 가능하다면 반영
        }
    }
    if(isput) return true; // 혹시 for문의 제일 마지막 경우에 스티커를 붙일 수 있었을 경우를 위함
    else return false; // 붙일 수 없는 경우
}

void rotate(){ // 스티커를 90도 회전 시키는 메서드
    for(int i = 0; i < r; i++){
        for(int j = 0; j < c; j++){
            tmp[i][j] = sticker[i][j];
        }
    }
    // n번째 열은 n번째 행으로, m번째 행은 (회전 전 스티커의 행의 개수 - 1) - m 열로
    for(int i = 0; i < c; i++){
        for(int j = 0; j < r; j++){
            sticker[i][j] = tmp[r-1-j][i];
        }
    }
    // 행과 열을 변경
    swap(r,c);
}

void putsticker(){
    if(checknput()) return; // 0도 회전 시 체크 후 붙일 수 있다면 붙이기 
    rotate(); // 90도
    if(checknput()) return; // 90도 회전 시 체크 후 붙일 수 있다면 붙이기 
    rotate(); // 180도
    if(checknput()) return; // 180도 회전 시 체크 후 붙일 수 있다면 붙이기 
    rotate(); // 270도
    checknput(); // 270도 회전 시 체크 후 붙일 수 있다면 붙이기
}


int main() {
    ios::sync_with_stdio(0);  
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m >> k;

    while(k--){
        cin >> r >> c;
        for(int i = 0; i < r; i++){
            for(int j = 0; j < c; j++){ // 스티커 입력 받기
                cin >> sticker[i][j];
            }
        }
        putsticker(); // 스티커를 붙이기
    }
    for(int i = 0; i < n; i++){ // 스티커가 붙은 부분 cnt
        for(int j = 0; j < m; j++){
            if(laptop[i][j] == 1) cnt++;
        }
    }
    cout << cnt;
}

'알고리즘 > 알고리즘 문제 풀이' 카테고리의 다른 글

(C++) 백준 1463번 - 1로 만들기  (0) 2023.05.07
(C++) 백준 15686번 - 치킨 배달  (0) 2023.05.01
(C++) 백준 15683번 - 감시  (0) 2023.04.18
(C++) 백준 2910번 - 빈도 정렬  (0) 2023.04.10
(C++) 백준 1181번 - 단어 정렬  (0) 2023.04.10
    '알고리즘/알고리즘 문제 풀이' 카테고리의 다른 글
    • (C++) 백준 1463번 - 1로 만들기
    • (C++) 백준 15686번 - 치킨 배달
    • (C++) 백준 15683번 - 감시
    • (C++) 백준 2910번 - 빈도 정렬
    용꿀
    용꿀

    티스토리툴바