백준 알고리즘 풀이 1780번 - 종이의 개수
2019. 9. 5. 17:39ㆍ프로그래밍/백준 알고리즘
분할 정복 문제.
- 알고리즘 -
1. 각 종이에 있는 모든 칸의 수가 같은지를 확인한다.
2. 모든 칸의 수가 같다면 그 칸에 있는 숫자 인덱스 값 1더한다.
3. 모든 칸의 수가 같지 않다면, 종이에 있는 칸의 갯수를 1/3로 줄이고, 첫 칸을 각 종이의 첫번째 항으로 한다.
- 예외 조건 -
1. -1은 인덱스가 될 수 없으므로 값을 저장할 때 다 +1을 하고 넣어주어야 한다.
첫 칸을 각 종이의 첫번째 칸으로 하는게 좀 어려웠다. 간단히 생각해보면 for문을 두개 돌려서 넣으면 된다.
-소스 코드-
#include <iostream>
using namespace std;
int map[2188][2188];
int count[4]={0,};
bool check(int num,int x,int y)
{
int isSame=true;
for(int i=y;i<y+num;i++){
for(int j=x;j<x+num;j++){
if(map[i][j]!=map[y][x]){
isSame=false;
return isSame;
}
}
}
return isSame;
}
// 종이의 모든 칸이 동일한지 동일하지 않은지 확인한다.
void seperate(int num, int x, int y)
{
if(check(num,x,y)){ //종이의 모든 칸이 동일하다면 종이 그대로 사용
count[map[y][x]+1]++; //-1은 인덱스에 올수 없으므로 모두 1을 더해준다. 예외조건
return;
}
int m=num/3;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){ //나누는 과정
seperate(m,x+j*m,y+i*m);//각 종이의 첫 칸을 첫칸으로 하고 다시 확인
}
}
}
int main()
{
int num;
cin>>num;
for(int i=0;i<num;i++){
for(int j=0;j<num;j++){
cin>>map[i][j];
}
}
seperate(num,0,0); // 맨 처음 종이는 제일 큰 종이 이므로 전체 종이의 맨 왼쪽 상단으로
for(int i=0;i<3;i++){
cout<<count[i]<<endl;
}
return 0;
}
'프로그래밍 > 백준 알고리즘' 카테고리의 다른 글
백준 알고리즘 풀이 10815번 - 숫자 카드 (0) | 2019.10.02 |
---|---|
백준 알고리즘 풀이 5014번 - 스타트링크 (0) | 2019.09.16 |
백준 알고리즘 문제 풀이 10610번 - 30 (0) | 2019.09.05 |
백준 알고리즘 1325번 - 효율적인 해킹 (0) | 2019.07.17 |
백준 알고리즘 2644번 - 촌수계산 (0) | 2019.07.09 |