BAEKJOON/Nationwide Internet Competition

BAEKJOON 9008번: Castle

杉山空 2022. 2. 15. 23:33
728x90

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

 

9008번: Castle

Your program is to read from standard input. The input consists of T test cases. The number of test cases T is given in the first line of the input. Each test case starts with integer n, the number of points, where 4 ≤ n ≤ 10,000. Each of the following

www.acmicpc.net

사용 알고리즘

깊이 우선 탐색

정렬

 

풀이

문제의 "the interior angle formed by its two incident edges is either 90° or 270°"라는 구절에서 알 수 있듯이 점들을 이은 선들은 무조건 90° or 270°의 각을 만들어야 한다.

따라서 다음과 같은 조건이 성립한다.

 

(x좌표가 같은 점들은 짝수, y좌표가 같은 점들 또한 짝수)

 

따라서 이를 먼저 확인해 주고 먼저 나온 순서대로 x좌표가 같은 점들과 y좌표가 같은 점들을 두 개씩 묶어서 이어준다.

 

이후 겹치는 선이 있는지 확인해 주고, DFS를 통해 처음 정점에서 다른 모든 점들을 탐색하고 다시 원래 점으로 돌아올 수 있는지 확인해준다. 돌아올 수 없거나, 겹치는 선이 있다면 simple rectilinear polygon 이 아니다.

 

마지막까지 모든 과정을 통과했다면 simple rectilinear polygon이며, Yes를 출력하면 된다.

아래는 예시 코드 이다.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <bits/stdc++.h>
using namespace std;
struct co{
    int x,y,z,w;
}A[10003];
inline bool cmp(co a,co b){
    return a.x<b.x||(a.x==b.x&&a.y>b.y);
}
vector<set<int> >vsi;
vector<bool>V;
vector<co>L;
int T,n;bool ans,ret;
bool g(int a,int b,int c,int d){
    if(b==1)return false;
    for(int i=0;i<=L.size();i++){
        if(L[i].z==2)continue;
        if(c>d)swap(c,d);
        if(L[i].x<a&&a<L[i].y&&c<L[i].w&&L[i].w<d){
            return true;
        }
    }
    return false;
}
void f(int a){
    for(int i=1;i<=n;i++){
        int j=i+1,cnt=1;
        while(A[i].x==A[j].x&&i<n){
            cnt++;
            if(cnt%2==0){
                vsi[A[i].z].insert(A[j].z);
                vsi[A[j].z].insert(A[i].z);
                co IN;IN.x=A[i].y,IN.y=A[j].y,IN.z=a,IN.w=A[i].x;
                if(IN.x>IN.y)swap(IN.x,IN.y);
                L.push_back(IN);
                if(g(A[i].x,a,A[i].y,A[j].y))ans=false;
            }
            i++;j=i+1;
        }
        if(cnt%2)ans=false;
    }
}
void dfs(int i,int anc){
    set<int>::iterator it;
    for(it=vsi[i].begin();it!=vsi[i].end();it++){
        if(*it!=anc&&*it==1)ret=true;
        if(V[*it])continue;V[*it]=true;
        dfs(*it,i);
    }
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);ans=true;ret=false;
        for(int i=1;i<=n;i++){scanf("%d%d",&A[i].x,&A[i].y);A[i].z=i;}
        sort(A+1,A+1+n,cmp);
        vsi.clear();V.clear(),L.clear();
        vsi.resize(n+1);V.resize(n+1);
        f(1);
        for(int i=1;i<=n;i++)swap(A[i].x,A[i].y);
        sort(A+1,A+1+n,cmp);
        f(2);
        if(!ans){
            printf("NO\n");
            continue;
        }
        V[1]=true;
        dfs(1,0);
        for(int i=1;i<=n;i++)if(!V[i])ret=false;
        if(ret&&ans)printf("YES\n");else printf("NO\n");
    }
    return 0;
}
cs
728x90

'BAEKJOON > Nationwide Internet Competition' 카테고리의 다른 글

BAEKJOON 9061번: 두 직사각형  (0) 2022.02.12
BAEKJOON 9027번: Stadium  (0) 2022.01.19