백준 1708 볼록 껍질

2021. 4. 29. 14:33· 알고리즘/백준(BOJ)
반응형

www.acmicpc.net/problem/1708

 

볼록 껍질 문제는 Convex Hull 문제라고 보면 된다.

 

Convex Hull 문제를 푸는 방식은 두 가지가 있다고 한다.

하나는 Graham Scan 방식과 Jarvis March 방식이다.

 

Jarvis March 방식은 나도 아직 잘 모르겠고,

 

Graham Scan 방식으로 문제를 풀었다.

 

알고리즘 설명은 이렇다.

1. 좌표값들이 주어진다.

2. 모든 좌표 중에서 극좌표를 결정한다.

3. 극좌표 결정은 y 좌표값이 가장 작고, 만약 y값이 같다면 x값이 작은 좌표를 찾아 극좌표로 결정하면 된다.

4. 극좌표를 기준으로 모든 좌표들을 반시계방향으로 좌표를 정렬한다.

5. 이 때, 정렬하는 방식은 ccw 방식을 사용하면 된다.

6. ccw > 0 이라면 반시계 방향이고, ccw == 0 이면 동일한 방향, ccw < 0 이면 시계 방향이라고 생각하면 된다.

7. 만약 ccw == 0 이 나와서 동일한 방향의 좌표가 나타난다면, 거리가 더 가까운 좌표를 먼저 오도록 정렬한다.

8. 정렬이 끝났다면, 처음 두 좌표를 stack에 넣어준다.

9. 첫 좌표를 기준으로 두 번째 좌표는 pop을 하고, 다음 n번째 좌표값과 계산하여 방향을 판단한다.

10. n번째 좌표가 반시계 방향이면 두 번째 좌표는 넣어준다.

11. (여기서 나는 엄청 헤맸다.) 만약 시계 방향이라면 두 번째 pop 되었던 좌표는 다시 stack에 넣어주면 안된다.

11-1. 이제 while문을 돌면서 stack의 사이즈가 2보다 작아지거나 n번째 좌표와 stack의 가장 위 두 좌표가 반시계방향이 나올 때까지 반복한다.

12. 마지막 좌표까지 순환을 하고 나서 최종 stack의 사이즈를 출력해주면 끝이난다.

#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <algorithm>

using namespace std;

struct Coordinate{
	double x, y;
} Polar;
int N;

long long ccw(Coordinate p1, Coordinate p2, Coordinate p3) {
	long long res = (p1.x * p2.y + p2.x * p3.y + p3.x * p1.y) - (p1.y * p2.x + p2.y * p3.x + p3.y * p1.x);
	if (res > 0) return 1; // Counter Clockwise Direction
	else if (res < 0) return -1; // Clockwise Direction
	else return 0; // Same Direction
}

long double distance(Coordinate a, Coordinate b) {
	return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

bool compare(Coordinate a, Coordinate b) {
	if (ccw(Polar, a, b) > 0) return true;
	else if (ccw(Polar, a, b) < 0) return false;
	else {
		if (distance(Polar, a) < distance(Polar, b)) {
			return true;
		}
		else {
			return false;
		}
	}
}

int main() {
	scanf("%d", &N);

	Coordinate* nArr = (Coordinate*)malloc(sizeof(Coordinate) * N);

	for (int i = 0; i < N; ++i) {
		scanf("%lf %lf", &nArr[i].x, &nArr[i].y);
	}
	
	// Initialize Polar Coordinate
	Polar = nArr[0];

	// Searching and Renewing Polar Coordinate
	for (int i = 1; i < N; ++i) {
		if (nArr[i].y < Polar.y) {
			Polar = nArr[i];
		}
		else if (nArr[i].y == Polar.y) {
			if (nArr[i].x < Polar.x) {
				Polar = nArr[i];
			}
		}
	}

	sort(nArr, nArr + N, compare);

	stack<Coordinate> s;

	s.push(nArr[0]);
	s.push(nArr[1]);

	Coordinate first, second;

	for (int i = 2; i < N; ++i) {
		while (s.size() >= 2) {
			second = s.top();
			s.pop();
			first = s.top();

			if (ccw(first, second, nArr[i]) > 0) { // 반시계방향
				s.push(second);
				break;
			}
		}

		s.push(nArr[i]);
	}

	printf("%d", s.size());

	return 0;
}
반응형

'알고리즘 > 백준(BOJ)' 카테고리의 다른 글

백준 9372 상근이의 여행  (0) 2021.05.05
백준 1197 최소 스패닝 트리  (0) 2021.05.05
백준 11758 CCW  (0) 2021.04.28
백준 14500 테트로미노  (0) 2021.04.26
백준 1697 숨바꼭질 C++  (0) 2021.04.20
'알고리즘/백준(BOJ)' 카테고리의 다른 글
  • 백준 9372 상근이의 여행
  • 백준 1197 최소 스패닝 트리
  • 백준 11758 CCW
  • 백준 14500 테트로미노
오뚜깅
오뚜깅
오뚜깅
오뚜깅
오뚜깅
전체
오늘
어제
  • 분류 전체보기
    • 취업인생
    • Programming
      • C & C++
      • Python
      • OpenCV
      • PCL
      • ROS
      • Deep learning
      • Network
    • 알고리즘
      • 이론
      • 백준(BOJ)
      • 프로그래머스(Programmers)
    • Project
    • IT
      • 우분투
    • 일상
      • 말씀 묵상
      • 끄적임
      • 영어 일기

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • c++code
  • rospy
  • PointCloudLibrary
  • clustering
  • graphicdriver
  • CUDA
  • OtsuAlgorithm
  • kmeansclustering
  • installubuntu
  • tensorflowversion
  • cv_bridge
  • 딥러닝환경구축
  • installcuda
  • pointcloud
  • cudaversion
  • CuDNN
  • cuda9.0
  • imageclustering
  • opencv
  • 사용자지정정규화공식
  • pytorch
  • 오츠알고리즘
  • 백준2798
  • cuda설치
  • DeepLearning
  • 우분투
  • 2292
  • C++
  • installcudnn
  • 백준2231

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
오뚜깅
백준 1708 볼록 껍질
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.