일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 에라토스테네스의 체
- 펜윅트리
- 이분매칭
- dfs
- LazyPropagation
- lis
- 누적합
- 크루스칼
- 수학
- lca
- 이진탐색
- MST
- 비트마스크
- 백준
- BFS
- 다익스트라
- boj
- DisjointSet
- 이분탐색
- 플로이드와샬
- 구현
- 삼분탐색
- 좌표압축
- 투포인터
- 그리디
- 세그먼트트리
- 정렬
- 위상정렬
- DP
- 브루트포스
Archives
- Today
- Total
lastknight00
[백준]직각다각형(17611) 본문
문제 링크 : [백준]직각다각형(17611)
문제 설명
모든 선분이 x축 혹은 y축과 평행한 선분들로 이루어진 직각다각형이 주어집니다.
이때, x축과 평행한 선분을 임의의 위치에 긋거나, y축과 평행한 선분을 임의의 위치에 그어 주어진 직각다각형과 교차하는 점들을 각각 셉니다.
그때 가장 많이 교차하는 선분이 몇개의 선분과 교차하는지 구하세요.
입력
N(선분의 갯수, 4 <= N <= 100,000)
Xi Yi(Xi, Yi의 좌표, -500,000 <= Xi, Yi <=500,000,점은 시계방향으로 주어집니다.)
12
0 0
0 3
1 3
1 1
2 1
2 3
5 3
5 0
4 0
4 2
3 2
3 0
출력
6
카테고리
#누적합
시간 복잡도 상한
O(NlogN)
해결 방법
- X축에 평행한 선과 Y축에 평행한 선을 나누어서 생각합니다.
- 처음 나온 점과 두번째 점을 비교하여, X좌표가 다르다면 X축, Y좌표가 다르다면 Y축과 평행한 선분입니다.
- 세번째 점과 네번째 점을 이은 선은 2번에서 구한 선과 평행합니다.(직각다각형이기 때문입니다.)
- 위와 같이 첫번째점을 시작으로 i번째 점과 i+1번째 점을 이은 선분들을 처리합니다.(X축 혹은 Y축과 평행한 모든 선분)
- 처리할 내용은 각 선분을 작은 좌표(-500,000에 가까운)를 기준으로 시작점과 끝점을 카운팅합니다.
- 시작점은 +1, 끝점은 -1
- 모든 선분에 대해 카운팅을 한 후, 왼쪽에서 오른쪽으로 누적합을 구합니다.
- 누적합은 현재 위치에 존재하는 선분의 갯수가 되고, 모든 구간에 대해 누적합이 가장 큰 수가 X축 혹은 Y축에 평행한 선분과 교차하는 선분 중 가장 많이 교차하는 점의 갯수입니다.)
- 2번부터 7번을 반복하는데, 이번에는 두번째 점과 세번째 점을 시작으로 출발하여, N번째 점과 첫번째 점을 잇는 선분들을 가지고 선분들을 처리합니다.
- 그러면 2번부터 생성한 선분과 정확하게 90도 차이가 나는 선분으로 2번에서 X축에 평행했다면 Y축으로 평행한 선분, Y축에 평행한 선분이었다면 X축에 평행한 선분이 됩니다.
- 두가지를 처리한 후 둘 중 큰 수를 출력합니다.
시간복잡도
O(M)(M은 좌표 범위)
코드
#include<iostream>
#include<algorithm>
#include<string.h>
#define M 500000
#define N 1000001
using namespace std;
int n,d[N],e[100000][2],i,j,k,s,t;
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);
cin>>n;
for(;i<n;i++)cin>>e[i][0]>>e[i][1];
for(j=0;j<2;j++){
memset(d,0,sizeof(d));
for(i=j;i<n;i+=2){
k=(i+1)%n;
if(e[i][0]!=e[k][0]){
d[min(e[i][0],e[k][0])+M]++;
d[max(e[i][0],e[k][0])+M]--;
}else{
d[min(e[i][1],e[k][1])+M]++;
d[max(e[i][1],e[k][1])+M]--;
}
}
for(t=k=i=0;i<N;i++)k+=d[i],t=max(t,k);
s=max(s,t);
}
cout<<s;
}
'PS' 카테고리의 다른 글
[백준]가로 블록 쌓기(18407) (0) | 2020.08.30 |
---|---|
[백준]화려한 마을(12895) (0) | 2020.08.30 |
[백준]사회망 서비스(SNS)(2533) (0) | 2020.08.22 |
[백준]K번째 최단경로 찾기(1854) (0) | 2020.08.16 |
[백준]거의 최단 경로(5719) (0) | 2020.08.16 |
Comments