알고리즘/알고리즘 문제풀이

2539번: 모자이크

b1ackhand 2022. 1. 24. 14:09

2022.01.23

 

문제 출처:

https://www.acmicpc.net/problem/2539

 

문제 분석:

잘못 칠해진 칸들의 좌표들을 정해줬을 때 이를 덮을 수 있는 정사각형 색종이의 가장 작은 크기를 구하는것.

사용할 정사각형의 색종이의 개수는 정해져 있다.

 

문제 해결:

문제에서 주어지는 예시 처럼 3cm 정사각형 색종이 4개로 덮을 수 있다.

그렇다면 4cm 정사각형 색종이 4개로도 덮을 수 있다.

즉, 답보다 큰 색종이들로는 모두 조건을 만족 하고, 정답보다 작은 크기의 색종이를 걸러내는 이분탐색을 사용하면 답에 한없이 가까워 질 수 있는 것이다.

 

이 때, 걸러내는 부분에서는 첫 잘못 칠해진 칸 기준으로 색종이를 점점 늘려갔을때 제한된 색종이 개수보다 많이 들면 false를 return 하는 것으로 답을 구할 수 있다.

 

 

내 소스코드:

#define F first
#define S second

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int INF = 987654321;

int row, column;
int limit;
int miss;
vector<pii> arr;

bool cmp(pii a, pii b)
{
   return a.S < b.S;
}

bool check(int size)
{
   int cnt = 1;
   int l = arr[0].S + size - 1;
   for (int i = 1; i < miss; i++)
   {
      if (arr[i].S <= l)
         continue;
      cnt++;
      l = arr[i].S + size - 1;
      if (cnt > limit)
         return false;
   }

   return true;
}

int main()
{
   scanf("%d %d", &row, &column);
   scanf("%d", &limit);
   scanf("%d", &miss);

   arr.resize(miss);

   int maxhi = -1;
   for (int i = 0; i < miss; i++)
   {
      int a, b;
      scanf("%d %d", &a, &b);
      arr[i] = {a, b};
      if (a > maxhi)
         maxhi = a;
   }

   sort(arr.begin(), arr.end(), cmp);

   int low = maxhi;
   int high = max(row, column);
   int ans = 0;

   while (low <= high)
   {
      int mid = (low + high) / 2;

      if (check(mid))
      {
         ans = mid;
         high = mid - 1;
      }
      else
         low = mid + 1;
   }
   printf("%d", ans);

   return 0;
}

 

고찰: 

이번 문제도 고민해 봤지만 못풀어서 힌트를 얻었다. dp, 구현 쪽이라고 생각했지만 전혀 아니었고 이분탐색이었다.

정해진 조건에 큰 범위에서 정확히 떨어지는 값을 찾는 문제라 이분탐색으로 판단할 수 있는 근거가 있는 것같다.

 

이분탐색으로 푸는 문제인것을 알아도 구현 할때마다 틀리는것 같다;

위의 While문에서도 low < high 라 하면 답이 나오지 않는것 처럼 큰 범위에서 접근 하기 떄문에 디버깅도 쉽지 않아서 어려운것 같다.

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

1063번: 킹  (0) 2022.02.05
10164번: 격자상의 경로  (0) 2022.02.03
2437번: 저울  (0) 2022.01.23
8958번: 0X퀴즈  (0) 2019.01.01
2577번: 숫자의 개수  (0) 2018.12.29