3. 사랑의 짝대기 (33점)
모든 사람은 서로 다른 사람을 가리킨다.
가리킨 사람을 계속 가리키다 보면 언젠간 다시 재현이로 돌아온다.
M을 재현이가 방문된 횟수로 나눈 나머지만큼만 가면 된다.
예제의 경우에는 1->3->4->1 같이 길이 3의 회로가 생기기 때문에
100을 3으로 나눈 나머지인 1번만 가보면 된다.
4. 사랑의 짝대기 (33점)
M번 사랑의 짝대기를 타고 간다.
사랑의 짝대기로 가리킨 사람이 있는 배열이 A라고 하고, 현재 가리킨
사람이 p라고 하면
p=A[p]
를 M번 반복하는 것으로 답을 이끌어낼 수 있다.
5. 사랑의 짝대기 (100점)
경로를 타고 가다가 cycle로 가게 된다.
경로를 타고 가다가 cycle이 확인되면 M을 cycle의 경로길이로 나눈
나머지로 처리를 해준다. 구현은 소스코드를 참고하길 바란다.
7. 사과의 그림판 (75점)
입력 받기: 문자열이나 문자가 쿼리에 들어오면 %s로 문자열 꼴로 받
은 후에 앞 문자를 확인하는 게 좋다. 자세한 구현은 소스코드를 참고
하기 바란다.
8. 사과의 그림판 (75점)
Flood fill: 그림 판을 채우는 것 처럼, 자기자신과 같으나 인접한 칸들
을 채우는 방식이다.
자신의 상하좌우 칸을 DFS를(재귀호출로 구현) 사용해서 같은 색으로
칠해나갈 수 있다.
꼭 코딩 해보기를 바란다. (작년, 제작년에 Flood Fill이 나왔음)
9. 사과의 그림판 (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의 범위를 직접 확인할 수도
있다.
10. 사과의 그림판(100점)
좌표압축을 하면 된다.
좌표압축이란 실제 중요한 좌표들은 색을 칠할 좌표들이라는 것을 이용,
필요 없는 좌표들을 모두 없애는 작업이다.
STL중에 unique란 STL은 unique(a.begin(),a.end()) 를 하면 연속으로
중복된 원소를 제거해 주고, 마지막 원소 다음 원소의 iterator(pointer
같은 개념)을 제공한다.
좌표압축을 한 후에 flood fill을 하면 된다.
11. 사과의 그림판(100점)
좌표압축의 방법은 X좌표를 배열 a에 넣고 정렬을 한 후
X[i]=lower_bound(a.begin(), a.end(), x[i]);
의 방법을 사용한다. 1의 개수를 셀 때는 a[i+1]-a[i]가 길이인 점을 이
용한다.
12. 화분
너비 W 안에 있는
최대값과 최소값의 차가 D이상
이 되게 하는 최소의 W를 찾아라
(Subtask 1: Greedy, Subtask 2: Sliding Window)
(koosaga: RMQ, parametric (? ????) )
13. 화분 (45점)
최솟값과 최댓값은 가장 끝에 위치할 때가 답이다.
양끝에 최솟값과 최댓값이 아니라면, 그 구간으로 답을 축소할 수 있다.
최솟값과 최댓값의 차이가 D이상이면 너비를 갱신해 준다.
구현이 간단하다.
14. 화분 (100점)
어차피 연속된 구간만 구해야 한다. 구간을 연속적으로 훑자!
Sliding Window: 어떤 구간의 왼쪽 제한과 오른쪽 제한을 번갈아 오른
쪽으로 이동해 가며 구간에 대해 보는 방식.
Double pointer 라는 테크닉으로도 부른다.
15. 화분 (100점)
화분 문제에서는 사용되는 중요한 함수(쿼리) 세 가지가 있다.
어떤 길이 N의 배열에 대해서, 아무것도 없는 [0,0)의 구간에서 시작해
현재 구간의 최댓값을 구한다.
구간을 오른쪽으로 한 칸 늘린다.
구간의 왼쪽을 한 칸 줄인다.
24. 화분 (100점)
3 1 4 1 5 9 2 6 5 3
설명: 제거는 간단하다. 왼쪽에서 제거 할 때, 제거하는 수가 수의 후보라면
단순히
후보에서 삭제해주는 것으로 충분하다. 그 수는 다시 볼 일이 없다.
25. 화분 (100점)
이런 자료구조를 deque를 사용해서 만들 수 있다.
deque 란 stack과 queue를 합쳐놓은 자료구조로
배열의 왼쪽과 오른쪽에
상수시간에 삽입삭제가 가능한 자료구조
이다. (double-ended queue, deck이라고 발음한다.)
26. 화분 (100점)
deque는 STL(표준 라이브러리)를 이용해서 쓸 수 있다.
deque는 표준 헤더 queue 에 정의되어 있다.
deque에는 다음과 같은 함수들이 있다.
27. 화분 (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에 가장 뒤쪽에 있는 수를 반환한다.
28. 화분 (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] 순으로 제외된다.
29. 화분 (100점)
DQ를 사용해서, 쿼리를 처리할 때 새로운 원소가 들어오면, 그 원소보
다 큰 원소가 발견될 때 까지 뒤에서 뺀 후, 그 원소를 뒤에 삽입하면
된다.
DQ를 사용해서, 쿼리를 처리할 때, 원소가 제거되면, 그 원소가 DQ안
에 들어있으면 가장 앞에 들어 있을 것이다. (DQ에는 배열 순서대로
들어간다.) 그 원소들을 제거하면 된다.
실제 화분문제는 넣을 때는 하나씩, 뺄 때는 차이가 D미만이 될 때 까
지 뺀다. 정렬도 해야 하므로 시간복잡도는 O(NlgN)이다.