알고스팟 문제 링크: https://www.algospot.com/judge/problem/read/JOSEPHUS

 

algospot.com :: JOSEPHUS

조세푸스 문제 문제 정보 문제 1세기에 살던 역사학자 조세푸스는 로마와의 전쟁에서 패해 N - 1명의 동료 병사들과 함께 출구가 없는 동굴에 포위당했다고 합니다. 동료 병사들은 로마에 항복하

www.algospot.com

조세푸스를 포함해서 병사들이 원형으로 앉아 순서대로 죽는다.

첫번째 병사가 처음으로 죽으면, 시계방향으로 k번째 사람이 죽기를 반복하다가 조세푸스를 포함한 병사 하나만 살아 남았을때 죽는것을 멈춘다고 한다.

이렇게 조세푸스가 마지막 두명중 하나가 되기 위해서는 조세푸스는 첫번째 병사로부터 몇자리 떨어진 곳에 있어야 하는지 구하는 문제이다.

 

이 문제를 풀려면 요소들을 순회하면서 삭제하는 작업을 반복적으로 해야한다.

이때 우리는 다양한 곳에서 요소를 추가/삭제할때 상수시간복잡도를 가지는 연결리스트( list )를 활용할 수 있다.

배열( vector, int[] )의 경우 맨 뒤 이외의 위치에서 원소 추가/삭제를 수행할때 선형시간복잡도를 가진다.

 

코드 원본: https://github.com/sbl133/JongmanBook/blob/main/18.%20linearDS/JOSEPHUS.cpp

 

GitHub - sbl133/JongmanBook

Contribute to sbl133/JongmanBook development by creating an account on GitHub.

github.com

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!

reference: 프로그래밍 대회에서 배우는 알고리즘 문제해결전략2

알고스팟 문제 링크: https://algospot.com/judge/problem/read/CHRISTMAS

 

algospot.com :: CHRISTMAS

크리스마스 인형 문제 정보 문제 크리스마스를 맞이하여 산타 할아버지는 전세계의 착한 어린이 K명에게 인형을 사주려고 한다. 산타 할아버지는 인형을 구입하기 위해서 유명한 인형가게인 "

algospot.com

상자마다 인형이 담겨있는 갯수가 각각 다르게 주어졌을때, 아이들k명에게 똑같은 갯수의 인형을 남는 인형 없이 나누어 주려 한다.

주문을 할때 'h번 상자부터 t번 상자까지 다 주세요'(h<=t)라고만 할 수있다.

한번 만 주문할 수 있는 경우 가능한 주문 방법,

한 상자가 주문에 중복으로 포함 되지 않게끔 여러번 주문 할수 있는 경우 최대 주문 횟수, 이렇게 두가지를 구하는 문제이다.

 

h에서 t까지 구입했을때 남기지 않고 나눠줄 수 있는 경우는 (psum[t]-psum[h-1])%k==0인 경우다.

 

한번 만 주문할 수 있는 경우 가능한 주문방법 = 나머지가 같은 것들끼리 묶고, 각 묶음에서 두개를 뽑는 조합의 경우

 

0번부터 i번까지의 상자가 있고, 여러번 주문 할때 최대 주문 횟수를 maxBuys(i)라 할때

maxBuys(i) = max( maxBuys(i-1), maxBuys(j)+1) (이때 j는 psum[i]==psum[j]인 i보다 작은 최댓값)

 

코드 원본: https://github.com/sbl133/JongmanBook/blob/main/17.%20partial%20sum/CHRISTMAS.cpp

 

GitHub - sbl133/JongmanBook

Contribute to sbl133/JongmanBook development by creating an account on GitHub.

github.com

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!

reference: 프로그래밍 대회에서 배우는 알고리즘 문제해결전략2

BOJ 문제 링크: https://www.acmicpc.net/problem/15686

 

15686번: 치킨 배달

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸

www.acmicpc.net

집과 치킨가게의 좌표가 N*N배열 형태로 주어진다.

m개의 치킨집을 남기고 구할 수 있는 각 집에서 가장 가까운 치킨 집과의 거리 합의 최솟값을 구하는 문제이다. 

집들과 치킨집들의 좌표를 각각의 벡터로 관리해준다.

좌표로 주어진 치킨집들중에 m개의 치킨집을 남겨야되는 작업은 재귀를 통해서 치킨집을 전체 순회하면서 구할 수 있다.

현재 치킨집을 남기는 경우와 폐업시키는 경우를 각각 재귀호출해서 더 작은 값을 반환 하는 쪽의 도시 치킨 거리를 반환한다.

 

코드 원본: https://github.com/sbl133/BOJ/blob/main/%2315686.cpp

 

GitHub - sbl133/BOJ

Contribute to sbl133/BOJ development by creating an account on GitHub.

github.com

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!

BOJ 문제 링크: https://www.acmicpc.net/problem/12865

 

12865번: 평범한 배낭

첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)

www.acmicpc.net

배낭에 담을 수 있는 무게가 제한 되있고, 각 물건들의 가치와 무게가 주어진다.

이때 배낭에 담을 수 있는 물건들의 가치의 최댓값을 구하는 문제이다.

주어진 물건들을 차례대로 순회하면서 담을지 안담을지를 결정한다. 담았을 경우 현재 배낭에 무게에 담고자 하는 물건의 무게를 추가하여 다음 물건을 결정하는 재귀를 호출하고, 안담았을 경우 현재배낭에 무게 그대로 다음 물건을 결정하는 재귀를 호출한다. 이 두 재귀중 큰 값을 반환하는 경우의 값을 return하면 된다.

 

코드 원본: https://github.com/sbl133/BOJ/blob/main/%2312865.cpp

 

GitHub - sbl133/BOJ

Contribute to sbl133/BOJ development by creating an account on GitHub.

github.com

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!

'Algorithm > BOJ' 카테고리의 다른 글

[BOJ] 백준 17828번 문자열 화폐 c++  (0) 2021.09.29
[BOJ] 백준 15686번 치킨 배달 c++  (0) 2021.09.22
[BOJ] 백준 14503번 로봇 청소기  (0) 2021.09.04
[BOJ] 백준 9251번 LCS  (0) 2021.09.02
[BOJ] 백준 2812번 크게 만들기  (0) 2021.09.02

알고스팟 문제 링크: https://algospot.com/judge/problem/read/GRADUATION

 

algospot.com :: GRADUATION

졸업 학기 문제 정보 문제 1학년은 노는 게 남는 거란 선배의 말을 철석같이 믿고, 전공 과목은 다 수강철회하고 교양 과목은 다 F 받는 방탕한 1학년을 보냈던 태우는 이제 와서 자신의 행동을

algospot.com

각 학기마다 열리는 전공과목을 선수과목과 학기당 들을 수 있는 최대 과목수를 고려하여 알맞게 수강했을때

졸업요건을 충족시키는 최소 이수 학기를 구하는 문제이다. 

현재 학기와 이제까지 들은 과목들이 주어졌을때 앞으로 들어야 하는 최소 학기를 반환하는 함수를 만들고

메모이제이션을 사용하는 다이나믹 프로그래밍기법을 이용하면 문제를 풀 수 있다.

이때 각 과목의 선수과목과 각 학기에 열리는 과목들을 비트마스크 기법을 사용하여 표현한 것에 주목하자.

 

코드 원본: https://github.com/sbl133/JongmanBook/blob/main/16.%20bitmask/GRADUATION.cpp

 

GitHub - sbl133/JongmanBook

Contribute to sbl133/JongmanBook development by creating an account on GitHub.

github.com

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!

reference: 프로그래밍 대회에서 배우는 알고리즘 문제해결전략2

알고스팟 문제 링크: https://algospot.com/judge/problem/read/NERDS

 

algospot.com :: NERDS

Nerd, or Not Nerd? 문제 정보 문제 Algospot.com's annual programming contest is drawing near, and there are overwhelming number of registrations (10,000+!). We have only 5 judges, so we cannot handle this number of teams. Therefore, we decided to admi

algospot.com

F= A * 신발 사이즈 + B * 분당 타이핑 속도 인 F가 있고 사람마다 신발사이즈와 분당 타이핑 속도가 주어졌을때 F가 일정 점수 이상인 사람을 너드로 추측한다고 하자.

사람마다 너드인지 여부와 신발 사이즈, 분당 타이핑 속도 이렇게 3가지 속성이 주어졌을때, 이 사람들의 너드 여부를 정확하게 추측할 수 있는 F= A * 신발 사이즈 + B * 분당 타이핑 속도 가 존재하는지를 예측 문제이다.

먼저 (신발 사이즈, 분당 타이핑 속도)를 (x,y)좌표로해서 점을 찍어보자.

이때 너드인 사람에 대해서 A*x + b*y >=T 가 성립해야 하므로 너드인점들과 너드가 아닌 점들을 나눌수 있는 직선이 존재해야 한다.

이것을 좀더 해결하기 쉽게 바꾸자면 너드인 점들로 이뤄진 볼록 다각형과 너드가 아닌점들로 이뤄진 볼록 다각형에 겹치는 부분이 있는지를 계산하면 된다.

그러기 위해서는 먼저 너드인 점과 너드가 아닌 점들을 각각 포함하는 볼록 다각형 두개를 만든다.

어느 한 다각형이 다른 다각형에 포함되거나, 두 다각형에 서로 닿는 두 변이 존재하는지를 확인한다.

포함여부를 확인할때는 어느 한 다각형의 꼭짓점 하나가 다른 다각형안에 있는지를 보면 되는데, 이것은 꼭짓점에서 반직선을 그어 다각형의 변과 교차하는 점을 확인하면 된다.

교하는 점의 갯수가 홀수면 꼭짓점은 다른 다각형 안에있고 짝수면 밖에있다. 

이때 주의할 점은 반직선이 다각형의 꼭짓점을 지날때인데 이것을 처리하기 위해서 반직선을 살짝 올린다는 개념으로 가로지르는지를 확인할때 부등호를 생략한다.

그러면 다각형의 꼭짓점 기준 위에 선분은 교차하고 아래 선분은 교차하지 않는것으로 처리되어 정상작동하게 된다.

 

코드원본: https://github.com/sbl133/JongmanBook/blob/main/15.%20ComputationalGeometry/NERD.cpp

 

GitHub - sbl133/JongmanBook

Contribute to sbl133/JongmanBook development by creating an account on GitHub.

github.com

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!

reference: 프로그래밍 대회에서 배우는 알고리즘 문제해결전략1

알고스팟 문제 링크: https://algospot.com/judge/problem/read/TREASURE

 

algospot.com :: TREASURE

보물섬 문제 정보 문제 위대한 해적 가이브러시 포피우드가 위대한 보물 투피스를 숨겨뒀다는 보물섬을 오랜 고난을 거쳐 찾아냈습니다. 가이브러시는 이 보물섬 어디엔가 투피스를 묻어뒀다

algospot.com

하나의 다각형과 하나의 직사각형에 교집합인 교집합 다각형의 넓이를 구하는 문제이다.

먼저 다각형을 직사각형의 각변을 포함하는 직선으로 잘랐을때, 해당 직선 왼쪽에 있는 다각형의 꼭짓점들, 직선과 다각형의 교차점들을 모두 저장한다.

직사각형 각각의 변들에 따라 이 작업을 총 4번 반복하면 교집합 다각형의 꼭짓점만을 저장할 수 있다.

다각형의 점들 p0, p1, p2, ... p(n-1)이 반시계 순서대로 배열되면 벡터p(i)와 벡터p((i+1)%n)의 외적을 모두(i=0부터 n-1까지) 합해서 2로 나누면 다각형의 넓이를 구할 수 있다.

 

코드원본: https://github.com/sbl133/JongmanBook/blob/main/15.%20ComputationalGeometry/TREASURE.cpp

 

GitHub - sbl133/JongmanBook

Contribute to sbl133/JongmanBook development by creating an account on GitHub.

github.com

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!

reference: 프로그래밍 대회에서 배우는 알고리즘 문제해결전략1

알고스팟 문제 링크: https://www.algospot.com/judge/problem/read/PINBALL

 

algospot.com :: PINBALL

핀볼 시뮬레이션 문제 정보 문제 동혁이는 새로 나온 핀볼 게임을 하고 있습니다. 이 핀볼 게임은 아주 큰 게임판에 여러 개의 장애물을 놓고, 밖에서 공을 던져 가장 많은 장애물을 맞추는 것을

www.algospot.com

공의 처음 위치와 진행방향과 원형태의 장애물들이 주어졌을때 공이 몇번 장애물에서 튕겨졌는지 순서대로 출력하는 문제이다.

공의 크기를 고려하는 대신에 장애물들의 반지름을 1씩 늘려서 문제를 해결 해보자

공이 처음위치 p에서 1초에 d만큼 굴러간다 하면 f(t) = p+td로 표현할 수 있다. 그럼 중심이 c이고 반지름이 r인 장애물과 교차하는 시간은 다음 식을 이용해 구할 수 있다.

|c-f(t)| = r       양변을 제곱하여 전개하면(dot를 내적이라 하면)

d(dot)dt^2 + 2(p-c)(dot)dt + c(dot)c+p(dot)p-2(c(dot)p)-r^2=0

이때 t는 항상 양수여야 하고 실근이 두개 반환될 때에는 둘중 작은값이 장애물과 부딪히는 시간이라는것은 직관적으로 알 수 있다.

t를 통해 구한 충돌지점(contact)을 이용하여 -dir을 contact-center에 사영시키고 해당 벡터를 d`라고 하자

2(dir+d`)-dir = dir+2d`이 충돌지점에서 장애물에 부딪힌 후 공의 진행방향이다.

 

코드원본: https://github.com/sbl133/JongmanBook/blob/main/15.%20ComputationalGeometry/PINBALL.cpp

 

GitHub - sbl133/JongmanBook

Contribute to sbl133/JongmanBook development by creating an account on GitHub.

github.com

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!

reference: 프로그래밍 대회에서 배우는 알고리즘 문제해결전략1

+ Recent posts