https://www.acmicpc.net/problem/17611
17611번: 직각다각형
입력의 첫 줄에는 단순직각다각형의 꼭지점의 개수를 나타내는 정수 n(4 ≤ n ≤ 100,000)이 주어지고, 이어지는 n개 줄 각각에 단순직각다각형 꼭지점의 좌표 (xi, yi)가 차례대로 주어진다. 주어지
www.acmicpc.net
[난이도] Gold1
[유형] 스위핑
[풀이]
가로 선분들과 세로 선분들을 나눠서 생각해보면
결국 가로 선분이 최대 몇개 겹칠 수 있는지, 세로 선분이 최대 몇개 겹칠 수 있는지를 각각 구해서
둘중 최댓값을 정답으로 출력하는 문제입니다.
번갈아 가면서 입력되는 가로 선분과 세로 선분을 각각 vector에 저장해줍니다.
a[i%2].push_back({l,1});
a[i%2].push_back({r,-1});
위와 같이 이런 스위핑 문제를 풀때 자주 사용하는 누적합 개념을 이용합니다.
선분이 시작되는 점에서 1을 더해주고 선분이 끝나는 점에서 1을 빼주면 어느 점에서 최대로 겹치는지
확인이 가능합니다.
#include <cstdio> #include <algorithm> #include <vector> using namespace std; int n,ans; pair<int,int> p[100000]; vector<pair<int,int>> a[2]; int main(){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&p[i].first,&p[i].second); for(int i=1;i<=n;i++){ int l,r,q=i,z=i-1; if(q==n) q=n-1,z=0; if(p[q].first==p[z].first) { l=min(p[q].second,p[z].second); r=max(p[q].second,p[z].second); }else{ l=min(p[q].first,p[z].first); r=max(p[q].first,p[z].first); } a[i%2].push_back({l,1}); a[i%2].push_back({r,-1}); } for(int i=0;i<2;i++){ sort(a[i].begin(),a[i].end()); int tmp=0; for(auto [t,v] : a[i]){ tmp+=v; ans=max(tmp,ans); } } printf("%d",ans); }
https://github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold1/17611.cpp
'Problem-Solving > BOJ' 카테고리의 다른 글
[BOJ/백준][Bronze3] 17614 : 369 (C++) (0) | 2022.07.04 |
---|---|
[BOJ/백준][Gold1] 17612 : 쇼핑몰 (C++) (0) | 2022.07.04 |
[BOJ/백준][Silver1] 17610 : 양팔저울 (C++) (0) | 2022.07.04 |
[BOJ/백준][Silver1] 17609 : 회문 (C++) (0) | 2022.07.04 |
[BOJ/백준][Bronze3] 17608 : 막대기 (C++) (0) | 2022.07.04 |