전에 색종이로 덮는 문제 푼 적 있었는데.. 있었지... 그 때는 색종이 만큼의 배열을 만들어서 덮은 수를 1로 바꿔가며 확인했었는데 이번에는 범위가 너무 커서 그렇게 못했다.
그래서 덮는 조건을 확인해가면서 몇 가지 유형으로 나눴다.
조건은 세 가지로 나눌 수 있다.
첫번째는 다 덮는거
두번째는 깔끔히 직사각형으로 덮는 거
그 외는 나머지 경우
조건은 다음 검은 종이를 얼마만큼 확인해야할지 기준으로 나눴다.
첫번째 경우는 다음 검은 종이를 확인할 필요가 없다. 그래서 그냥 NO를 출력하고 종료
그 외 경우는 어쩔 수 없이 다음 종이로 다 덮히는지 판단...
두번째 경우는 다 덮히는 지 확인하는 건 같지만 흰 종이의 범위를 줄일 수 있다.
~~나머지는 집 가서~~
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector<int> x(7);
vector<int> y(7);
for (int i = 1; i < 7; i++)
scanf("%d %d", &x[i], &y[i]);
if (x[3] <= x[1] && y[3] <= y[1] && x[2] <= x[4] && y[2] <= y[4])
{
printf("NO");
return (0);
}
if (y[3] <= y[1] && y[2] <= y[4])
{
if (x[1] < x[4] && x[3] <= x[1] && x[4] < x[2])
x[1] = x[4];
if (x[3] < x[2] && x[2] <= x[4] && x[1] < x[3])
x[2] = x[3];
}
else if (x[3] <= x[1] && x[2] <= x[4])
{
if (y[1] < y[3] && y[3] < y[2] && y[2] <= y[4])
y[2] = y[3];
if (y[1] < y[4] && y[3] <= y[1] && y[4] < y[2])
y[1] = y[4];
}
if (x[5] <= x[1] && y[5] <= y[1] && x[2] <= x[6] && y[2] <= y[6])
{
printf("NO");
return (0);
}
printf("YES");
return (0);
}
휴 드디어 다풀었다.
어려운 알고리즘 기법! 이런 문제는 아니었는데 구현이 복잡했다.
풀면서 이걸 시간 내에 다 풀 수 있을까?? 이런 생각 계속 들었음. 아마 못했을 듯 ~.~
놀라운 걸 배워왔다
전에 ㅂㅣAsk휴 (써방임) 과제할 때 얘의 존재에 대해 들었는데 어떻게 사용할지 몰라서 패스했었다.
암튼.. 이 문제는 좌표압축을 쓰면 빠르고 깔끔하게 풀린다.
사각형이 3개 밖에 없어서 이 꼭지점 6개를 좌표로 만들고 전의 상자 색칠하는 문제처럼 풀면 바로 풀린다.
신기~~
lower_bound 기억 안 나서 다시 공부했다
https://burningjeong.tistory.com/123
lower_bound, upper_bound
사용 예시 사용방법
burningjeong.tistory.com
이런 애였지
아 여기 lower_bound 대신에 find를 써도 되지 않을까 궁금했는데 find는 O(N)이 걸리고 lower_bound()는 이분탐색으로 찾아서 O(logN)이 걸린다. 알아둬야지 ^~^
신기하구만..
신기해..
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Mapping
{
public :
void init(const vector<int>& raw, int base = 0)
{
start = base;
arr = raw;
sort(arr.begin(), arr.end());
arr.erase(unique(arr.begin(), arr.end()), arr.end());
}
int get_idx(int k)
{
return start + (lower_bound(arr.begin(), arr.end(), k) - arr.begin());
}
int get_value(int idx)
{
return arr[idx - start];
}
int size()
{
return arr.size();
}
private:
int start;
vector<int> arr;
};
int color[6][6];
int main()
{
vector<int> x(6), y(6);
for (int i = 0; i < 6; i++)
scanf("%d %d", &x[i], &y[i]);
Mapping xmap, ymap;
xmap.init(x);
ymap.init(y);
for (int i = 0; i < 6; i++)
{
x[i] = xmap.get_idx(x[i]);
y[i] = ymap.get_idx(y[i]);
}
for (int i = 2; i < 6; i += 2)
for (int sx = x[i]; sx < x[i + 1]; sx++)
for (int sy = y[i]; sy < y[i + 1]; sy++)
color[sx][sy] = 1;
for (int sx = x[0]; sx < x[1]; sx++)
{
for (int sy = y[0]; sy < y[1]; sy++)
{
if (color[sx][sy] == 0)
{
printf("YES");
return 0;
}
}
}
printf("NO");
return (0);
}
코드는 이렇다
'코드포스' 카테고리의 다른 글
[코드포스 Practice13] A. Kuriyama Mirai's Stones (0) | 2020.03.07 |
---|---|
[코드포스 Practice13] 후기 (0) | 2020.03.07 |
[코드포스 Practice12] C. Given Length and Sum of Digits... (0) | 2020.02.28 |
[코드포스 Practice12] B. New Year and Buggy Bot (0) | 2020.02.28 |
[코드포스 Practice12] A. k-rounding (0) | 2020.02.28 |