koistudy 지역본선 2차모의고사 풀이집

31
모모모모 13003 HYEA

Upload: ho94949

Post on 05-Aug-2015

39 views

Category:

Education


0 download

TRANSCRIPT

Page 1: KOISTUDY 지역본선 2차모의고사 풀이집

모의고사

13003 HYEA

Page 2: KOISTUDY 지역본선 2차모의고사 풀이집

사랑의 짝대기

M 번 사랑의 짝대기를 타자(Subtask 1: 단순 구현 ; 2, 3: 그래프 이론 )

Page 3: KOISTUDY 지역본선 2차모의고사 풀이집

사랑의 짝대기 (33 점 )

모든 사람은 서로 다른 사람을 가리킨다 .

가리킨 사람을 계속 가리키다 보면 언젠간 다시 재현이로 돌아온다 .

M 을 재현이가 방문된 횟수로 나눈 나머지만큼만 가면 된다 .

예제의 경우에는 1->3->4->1 같이 길이 3 의 회로가 생기기 때문에 100 을 3 으로 나눈 나머지인 1 번만 가보면 된다 .

Page 4: KOISTUDY 지역본선 2차모의고사 풀이집

사랑의 짝대기 (33 점 )

M 번 사랑의 짝대기를 타고 간다 .

사랑의 짝대기로 가리킨 사람이 있는 배열이 A 라고 하고 , 현재 가리킨 사람이 p 라고 하면

p=A[p]

를 M 번 반복하는 것으로 답을 이끌어낼 수 있다 .

Page 5: KOISTUDY 지역본선 2차모의고사 풀이집

사랑의 짝대기 (100 점 )

경로를 타고 가다가 cycle 로 가게 된다 .

경로를 타고 가다가 cycle 이 확인되면 M 을 cycle 의 경로길이로 나눈 나머지로 처리를 해준다 . 구현은 소스코드를 참고하길 바란다 .

Page 6: KOISTUDY 지역본선 2차모의고사 풀이집

사과의 그림판

그림판을 채우자(Subtask 1: Flood fill; Subtask 2: 좌표 압축 )

Page 7: KOISTUDY 지역본선 2차모의고사 풀이집

사과의 그림판 (75 점 )

입력 받기 : 문자열이나 문자가 쿼리에 들어오면 %s 로 문자열 꼴로 받은 후에 앞 문자를 확인하는 게 좋다 . 자세한 구현은 소스코드를 참고하기 바란다 .

Page 8: KOISTUDY 지역본선 2차모의고사 풀이집

사과의 그림판 (75 점 )

Flood fill: 그림 판을 채우는 것 처럼 , 자기자신과 같으나 인접한 칸들을 채우는 방식이다 .

자신의 상하좌우 칸을 DFS 를 ( 재귀호출로 구현 ) 사용해서 같은 색으로 칠해나갈 수 있다 .

꼭 코딩 해보기를 바란다 . ( 작년 , 제작년에 Flood Fill 이 나왔음 )

Page 9: KOISTUDY 지역본선 2차모의고사 풀이집

사과의 그림판 (75 점 )

int dx[4]={-1,0,1,0};int dy[4]={0,1,0,-1}; // 상하좌우 좌표를 다음과 같은 방식으로 표현한다 .void dfs(int a,int b,int c,int d){    if(board[a][b]!=d) return; // 현재 색이 원래 판 색과 같지 않으면 끝낸다 .    board[a][b]=c; // 현재 색을 채운다 .    for(int i=0;i<4;i++)        dfs(a+dx[i],b+dy[i],c); // 상하좌우에 대해 반복한다 .    return;}

DFS 의 구현에는 다양한 방법이 있다 . 이 방법은 경계를 -1 의 색으로 칠해놓아서 경계로 나가지 못하는 방법이다 . a, b 의 범위를 직접 확인할 수도 있다 .

Page 10: KOISTUDY 지역본선 2차모의고사 풀이집

사과의 그림판 (100 점 )

좌표압축을 하면 된다 . 좌표압축이란 실제 중요한 좌표들은 색을 칠할 좌표들이라는 것을 이용 ,

필요 없는 좌표들을 모두 없애는 작업이다 .

STL 중에 unique 란 STL 은 unique(a.begin(),a.end()) 를 하면 연속으로 중복된 원소를 제거해 주고 , 마지막 원소 다음 원소의 it-erator(pointer 같은 개념 ) 을 제공한다 .

좌표압축을 한 후에 flood fill 을 하면 된다 .

Page 11: KOISTUDY 지역본선 2차모의고사 풀이집

사과의 그림판 (100 점 )

좌표압축의 방법은 X 좌표를 배열 a 에 넣고 정렬을 한 후

X[i]=lower_bound(a.begin(), a.end(), x[i]);

의 방법을 사용한다 . 1 의 개수를 셀 때는 a[i+1]-a[i] 가 길이인 점을 이용한다 .

Page 12: KOISTUDY 지역본선 2차모의고사 풀이집

화분

너비 W 안에 있는

최대값과 최소값의 차가 D 이상

이 되게 하는 최소의 W 를 찾아라(Subtask 1: Greedy, Subtask 2: Sliding Window)

(koosaga: RMQ, parametric (? ????) )

Page 13: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (45 점 )

최솟값과 최댓값은 가장 끝에 위치할 때가 답이다 . 양끝에 최솟값과 최댓값이 아니라면 , 그 구간으로 답을 축소할 수 있다 .

최솟값과 최댓값의 차이가 D 이상이면 너비를 갱신해 준다 .

구현이 간단하다 .

Page 14: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

어차피 연속된 구간만 구해야 한다 . 구간을 연속적으로 훑자 !

Sliding Window: 어떤 구간의 왼쪽 제한과 오른쪽 제한을 번갈아 오른쪽으로 이동해 가며 구간에 대해 보는 방식 . Double pointer 라는 테크닉으로도 부른다 .

Page 15: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

화분 문제에서는 사용되는 중요한 함수 ( 쿼리 ) 세 가지가 있다 .

어떤 길이 N 의 배열에 대해서 , 아무것도 없는 [0,0) 의 구간에서 시작해

현재 구간의 최댓값을 구한다 .

구간을 오른쪽으로 한 칸 늘린다 .

구간의 왼쪽을 한 칸 줄인다 .

Page 16: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

이 아이디어에서는

답이 될 수 있는 칸들을 사용해서

모두 상수시간 안에 쿼리를 처리한다 .

Page 17: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

3 1 4 1 5 9 2 6 5 3

Page 18: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

3 1 4 1 5 9 2 6 5 3

설명 : 3 은 답이 될 수 있는 수이다 .

Page 19: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

3 1 4 1 5 9 2 6 5 3

설명 : 1 은 답이 될 수 있는 수이다 . 구간이 왼쪽으로 한 칸 축소되면 1 이 답이다 .

Page 20: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

3 1 4 1 5 9 2 6 5 3

설명 : 4 가 구간에서 제외되려면 3 과 1 이 제외되어야 하므로 , 3 과 1 은 절대 답이 될 수 없다 . 그러므로 4 가 답의 유일한 후보이다 .

Page 21: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

3 1 4 1 5 9 2 6 5 3

설명 : 왼쪽에서 수 3 개가 제외되면 1 이 답이 될 수 있다 .

Page 22: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

3 1 4 1 5 9 2 6 5 3

설명 : 같은 방법으로 후보를 구하면 9 와 6 이라는 것을 알 수 있다 . 여기서 중요한 고찰을 할 수 있다 .

Page 23: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

후보인 수들은 오른쪽에자기보다 큰 수가 없다 .

Page 24: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

3 1 4 1 5 9 2 6 5 3

설명 : 제거는 간단하다 . 왼쪽에서 제거 할 때 , 제거하는 수가 수의 후보라면 단순히 후보에서 삭제해주는 것으로 충분하다 . 그 수는 다시 볼 일이 없다 .

Page 25: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

이런 자료구조를 deque 를 사용해서 만들 수 있다 .

deque 란 stack 과 queue 를 합쳐놓은 자료구조로

배열의 왼쪽과 오른쪽에

상수시간에 삽입삭제가 가능한 자료구조 이다 . (double-ended queue, deck 이라고 발음한다 .)

Page 26: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

deque 는 STL( 표준 라이브러리 ) 를 이용해서 쓸 수 있다 .

deque 는 표준 헤더 queue 에 정의되어 있다 .

deque 에는 다음과 같은 함수들이 있다 .

Page 27: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

#include<queue>

std::deque<int> DQ;

DQ.push_front(a); //DQ 의 앞쪽에 a 를 넣는다 .

DQ.push_back(a); //DQ 의 뒤쪽에 a 를 넣는다 .

DQ.empty(); //DQ 가 비어있으면 true, 아니면 false 를 반환한다 .

DQ.size(); //DQ 에 들어있는 원소의 수를 반환한다 .

DQ.front(); //DQ 에 가장 앞쪽에 있는 수를 확인한다 .

DQ.pop(); //DQ 에 가장 뒤쪽에 있는 수를 반환한다 .

Page 28: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

#include<queue>

std::deque<int> DQ; //DQ 의 구조 > []

DQ.empty(); // DQ 가 비어있으므로 true 를 반환한다 .

DQ.push_front(3); //DQ 의 구조 > [3]

DQ.back();// 가장 뒤쪽에 있는 수는 3 이므로 3 을 반환한다 .

DQ.push_back(7); //DQ 의 구조 > [3, 7]

DQ.push_front(9); //DQ 의 구조 > [9, 3, 7]

DQ.front(); // 가장 앞쪽에 있는 수는 9 이므로 9 를 반환한다 .

DQ.back(); // 가장 뒤쪽에 있는 수는 7 이므로 7 을 반환한다 .

DQ.size(); //DQ 의 원소가 3 개이므로 3 을 반환한다 .

DQ.pop_back(); DQ.pop_back(); // [9, 3, 7]-> [9, 3] -> [9] 순으로 제외된다 .

Page 29: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

DQ 를 사용해서 , 쿼리를 처리할 때 새로운 원소가 들어오면 , 그 원소보다 큰 원소가 발견될 때 까지 뒤에서 뺀 후 , 그 원소를 뒤에 삽입하면 된다 .

DQ 를 사용해서 , 쿼리를 처리할 때 , 원소가 제거되면 , 그 원소가 DQ 안에 들어있으면 가장 앞에 들어 있을 것이다 . (DQ 에는 배열 순서대로 들어간다 .) 그 원소들을 제거하면 된다 .

실제 화분문제는 넣을 때는 하나씩 , 뺄 때는 차이가 D 미만이 될 때 까지 뺀다 . 정렬도 해야 하므로 시간복잡도는 O(NlgN) 이다 .

Page 30: KOISTUDY 지역본선 2차모의고사 풀이집

화분 (100 점 )

Alternative: parametric + RMQ

사과가 설명해 주겠지 (?)

Page 31: KOISTUDY 지역본선 2차모의고사 풀이집

광부

IOI 2007 기출이라는것 같다 .

필자가 부산을 가고 있으므로 부산에 도착할때 까지 열심히 풀어 풀이를 업로드 하도록 하겠다 .