이분탐색의 종료조건과 경계조건 정리
이분탐색의 종료조건과 경계조건, 즉 while문에 무엇이 들어가야 하는지, lo와 high를 각각 무슨 값으로 설정해야 하는지를 저를 포함해서 헷갈리시는 분들이 있는 거 같아서 한번 정리해 보려고 합니다.
이분탐색의 종료조건과 경계조건, 즉 while문에 무엇이 들어가야 하는지, lo와 high를 각각 무슨 값으로 설정해야 하는지를 저를 포함해서 헷갈리시는 분들이 있는 거 같아서 한번 정리해 보려고 합니다.
본 글은 익명의 유저님께서 작성하신 글을 합의하에 제가 이어받아 옮긴 글입니다. 새롭게 바뀐 내용이 있으면 제가 지속적으로 업데이트해 나가겠습니다.
채점 서버에는 한 쌍 이상의 입력 파일과 출력 파일이 있습니다.코드를 제출하면 그 코드에 입력 파일에 적힌 대로 입력하고 나타나는 출력을 출력 파일과 비교합니다. 모든 입력/출력 파일에 대해 코드가 문제 없이 올바른 출력을 내야 합니다. 여기서 "올바름"이란 것은 단순히 정답과 같은 값이 아니라 같은 출력을 의미합니다. 예를 들어 45.0을 출력해야 하는데 45나 45.00을 출력하면 오답입니다.
입출력 파일은 공개되지 않습니다. 예제는 데이터 중 극히 일부에 불과합니다. 예제는 자신의 코드가 맞을 것임을 확신하는 용도가 아니라, 입출력의 형식을 확인하고 문제의 설명을 검토하는 용도로 사용해야 합니다.
스페셜 저지가 있는 문제에는 출력이 올바른지 검사하는 채점 코드가 따로 있습니다. 그러므로 "올바른 출력"은 여러 가지가 될 수 있고, 그 중 하나만 출력하면 됩니다. 예를 들어 $10^{-2}$ 이하의 오차를 허용하는 문제라면 출력과 정답의 오차가 $10^{-2}$ 이하인지 검사하는 코드가 있습니다. 그런 문제에서 정답이 45.0이라면 45나 45.00을 출력해도 정답을 받을 수 있습니다.
if (3 <= N && N <= 5000)와 같은 조건문을 넣어 별도로 검증을 하지 않으셔도 괜찮습니다.
시간 제한은 각 파일마다 따로따로 적용됩니다. 즉 시간 제한이 1초면 첫 번째 파일에 1초, 두 번째 파일에 1초, ..., 마지막 파일에 1초 이내가 걸려야 합니다. 채점 현황에서 볼 수 있는 "시간"은 가장 오래 걸린 파일에서의 구동 시간을 나타냅니다.
메모리 제한도 마찬가지인데, 한 순간에라도 지정된 메모리를 초과하면 안 됩니다. 채점 현황에서 볼 수 있는 "메모리"는 최대 메모리 사용량을 나타냅니다.
언어에 따라 시간이나 메모리가 초과되고도 정답을 받을 수 있는데, 그 언어가 정해진 시간/메모리 보너스를 받기 때문입니다. https://www.acmicpc.net/help/language
"첫 줄에 테스트케이스의 개수 $T$가 주어진다." 또는 "입력은 여러 개의 테스트케이스로 이루어져 있다." 같은 문제는 그 $T$개의 테스트케이스가 한 파일에 들어있다는 뜻입니다. 그런데 시간과 메모리 제한은 각 파일마다 따로따로 적용된다고 했으므로 주어진 시간 안에 한 파일에 들어있는 모든 테스트케이스가 돌아가야 합니다.
너무 많아져서 아래 글로 분리했습니다. https://www.acmicpc.net/blog/view/70
Q. 파이썬으로 ○○○○번을 시간 내에 못 푸나요?
A. 파이썬이 원래 극도로 느리기 때문에 제대로 된 풀이로도 시간초과가 날 수 있습니다. 그럴 때는 PyPy로 제출하시면 웬만한 문제들은 풀 수 있습니다. 아주 어려운 문제라면 이것도 안 될 수도 있습니다.
하지만 반대로 언어 탓부터 하는 것도 바람직한 자세는 아닙니다. 알고 보니 시간 복잡도가 너무 커서 시간 초과일 수도 있고, 그 사실을 알아차리지 않은 채로 C++ 등으로 다시 짜다간 다시 시간 초과를 받고 코딩 시간을 낭비하게 됩니다. 항상 알고리즘의 논리부터 의심하는 것이 바람직합니다.
Q. 문제의 정답 비율은 어떻게 계산되나요?
A. https://www.acmicpc.net/problem/15595
Q. 문제 번호가 왜 1000부터 시작하나요?
A. https://www.acmicpc.net/board/view/86719
Q. 하스켈 언어의 지원 계획이 있나요?
A. 채점에 문제가 있어서 해결될 때까지 보류됩니다. 이 글(링크)과 이 글(링크)을 참조해 주세요.
Q. 번역은 어떻게 하나요?
A. 번역 기능이 있었으나, 오역의 문제가 많이 발생하여 중단되었습니다.
Q. 출제는 어떻게 하나요?
A. https://www.acmicpc.net/help/problem-add
추후 내용이 추가될 수 있습니다.
본 글은 익명의 유저님께서 작성하신 글을 합의하에 제가 이어받아 옮긴 글입니다. 새롭게 바뀐 내용이 있으면 제가 지속적으로 업데이트해 나가겠습니다.
원래는 BOJ 101 글에 있었던 내용인데, 쓸 내용이 너무 많아져서 독립된 글로 옮겼습니다.
return 1, 여러 언어의 exit(1) 등으로 0이 아닌 exit code를 내면 런타임
에러입니다.


ios:sync_with_stdio(false);를 한 뒤에는 iostream과 stdio를 혼용하면 안 됩니다.
iostream에 해당하는 것으로 cin, cout 등이 있고, stdio에 해당하는 것으로
printf, scanf, putchar, getchar, puts, gets 등이 있습니다.
float는 너무 부정확해서
유의미한 사용이 사실상 불가능합니다. double을
씁시다.
A[(i - 1) % N] 같은 걸 하면 큰일납니다. 이럴 때는 (i + N - 1) % N을 하면 됩니다.
int A[100000]을
잡았는데 for (int i = 1; i <= 100000; i++)을 한다든지, "문자열의
길이는 10만 이하이다."라고 해서 char A[100000]을 잡았는데 널
문자때문에 사실 100001개가 필요하다든지... 그래서 [100055]처럼
실제 최대값보다 조금 많이 잡으면 인덱싱 오류가 날 가능성이 줄어듭니다.
sizeof를
권장합니다.
strlen은 $\mathcal{O}(N)$입니다. 따라서
for(int i = 0; i < strlen(s); i++)은 좋지 않습니다.
s의 크기가 변하지 않는다면 strlen(s)를 미리 구해둔
다음 그 값으로 for 루프를 돌립시다.
memset은 0과 -1만 가능합니다.
https://www.acmicpc.net/board/view/23217#comment-40375
strcmp는 -1, 0, 1이 아니라
음의 정수, 0, 양의 정수를 반환합니다.
atoi에는 널 문자로 끝나는 문자열을 넘겨줘야지, char형 하나의
주소를 넘겨주면 안 됩니다. 참고로 숫자 c 하나를 int로 바꾸려면
c - '0'을 하면 됩니다.
A[x] = x++;는 매우 위험합니다. 적어도 C++14까지는 undefined
behavior였습니다. (C++17에서의 동작은 잘 아시는 분이 제보 바랍니다.)
a <= b <= c는 (a <= b) <= c로 계산됩니다. "b가 a
이상, c 이하임"을 나타내려면 a <= b && b <= c라고 해야 합니다.
scanf("%d", &a)를 했는데 EOF를 만나면 a가 0이나
EOF가 되는 게 아니라 저 함수 자체가 EOF를 반환합니다.
fflush(stdin)은 표준이 아닙니다. rewind(stdin)도
표준이 아닙니다. fflush는
출력 스트림만 비울 수 있습니다.
itoa는 표준이 아닙니다. 그 대신 sprintf를 쓰세요.
package boj; 같은 건 모두 지우고 제출해야 하며, 클래스 이름은
Main이어야 합니다.
Scanner는 하나만 만드세요.LinkedList의 $x$번째 원소 찾기는 $\mathcal{O}(x)$입니다.Integer 등 wrapper class의 객체끼리는 == 으로
비교하면 안 되고 equals 메서드로 비교해야 합니다.
list.pop(0), list.index, list.insert, list.count, x in list,
list[:-1]
등은 다 $\mathcal{O}(N)$입니다. 이외에도 $\mathcal{O}(N)$이 걸리는 list 연산이 굉장히 많습니다.
https://wiki.python.org/moin/TimeComplexity
collections.deque를 써야 합니다.
queue.Queue도 안 됩니다. 이건 멀티스레딩을 위해
만들어진 큐이고 매우 느립니다.
sys.setrecursionlimit으로 이 깊이를 조절할 수 있습니다.
int(a / b) 말고 a // b를 써야 합니다.
맨 위의 "부동소수점 자료형은 나타내는 수의 범위가 넓지만 ..."을 읽어보세요.
s + c의 시간복잡도는 $\mathcal{O}(\mathrm{len}(S))$입니다.
예전에는 CPython에서 $\mathcal{O}(1)$였는데 특정 버전부터 느려진 것 같습니다. 자세한
정보를 찾는 대로 추가하겠습니다...
일반 Python에는 해당되지 않는 사항입니다.
print가 sys.stdout.write보다 많은 메모리를
차지합니다. 구체적으로, print를 많이 사용할 수록 메모리도 많이
사용됩니다. 2020년 8월 9일 현재 Atcoder에서도 같은 현상이 나는 것으로
확인했습니다.
sys.setrecursionlimit에서 설정해 놓은 재귀 깊이가 클 수록
메모리 사용량도 큽니다. 2020년 8월 9일 기준으로 Codeforces에서도 같은 현상이
나는 것으로 확인했습니다.
추가해야 할 내용을 제보받으면 추가하겠습니다.
안녕하세요. 단계별로 풀어보기 관리자 @jhnah917입니다. 최근 변경 내역과 이후 계획에 대해 안내해 드립니다.
자연수의 곱, 합성곱을 위한 FFT를 설명하는 다른 블로그를 찾아가 보면 보통 학부생 수준의 배경지식을 요구하거나 구현만 알려주는 곳이 많습니다. 자세하게 증명하는 한국어 글이 없어서 되게 힘들었는데, 여러분은 힘들게 찾아보지 않았으면 해서 글을 써 보았습니다.
이 글은 FFT의 구현이 아니라 DFT, FFT를 이해하는 데 초점을 둡니다. 코드에 대한 설명은 하지 않습니다.
증명을 이해하기 위해선 아래의 배경지식이 필요합니다.
---------미리 보기 방지-----------
---------미리 보기 방지-----------
---------미리 보기 방지-----------
가끔 "같은 프로그램을 Python 3 으로 제출하면 시간 초과를 받는데, Pypy3 으로 제출하면 맞았습니다를 받습니다. 왜 그런가요?" 같은 질문을 보게 됩니다. 이 글에서는 이런 종류의 질문에 대한 답변을 해 보려고 합니다.
Python 3 은 언어 명세입니다. 프로그램의 문법을 정의하고, 각각의 문장이 가진 의미 (= 문장을 실행하면 달라지는 변화)를 정합니다. 이렇게 Python 3 언어 명세를 정한 사람들은 그 언어 명세를 따르는 구현체 또한 제작하여 언어 명세와 같이 공개/배포합니다.
그 뒤, 몇몇 사람들은 배포된 Python 3 의 언어 명세를 이용하여 별도의 구현체를 만들기도 합니다. Pypy3 이나 IronPython, Jython 등이 여기에 해당합니다.
알고리즘 공부를 시작할 때 맨 처음 만나는 개념 중 시간, 공간 복잡도가 있습니다. 안타깝게도, 이는 오개념이 가장 많이 퍼진 주제이기도 합니다. 여러 오개념이 있지만 이 글에서는...
"빅-Ω 표기법은 최선의 경우를 다룰 때 사용한다. 빅-Ө 표기법은 평균의 경우를 다룰 때 사용한다. 빅-O 표기법은 최악의 경우를 다룰 때 사용한다."
...라는 오개념을 다룹니다. 이 주장은 각종 블로그 글은 물론, 이름 있는 출처에도 가끔씩 나오며 심지어 책으로도 나왔습니다.
어둠의 아이콘
백준 크래딧을 찾으면 된다.
어둠의 초록색 입체 그리드
solved.ac 테마를 뭘로 바꿔볼까?
팽귄과 마작을
1811?번을 풀면 얻을 수 있습니다! p.s 이 작성자는 얻는 방법은 알지만 어려워서 풀지 못했다. 그럼 어떻게 알았지? 그건 비밀!
https://www.acmicpc.net/problem/31442
에디토리얼과 결이 다른 풀이가 있어 공유합니다.
처음에 $1$이 $N$개이므로, 최소 $N - 1$번 작업을 수행해야 $N$이 만들어집니다. 한편 처음 $A$의 길이에서 작업의 가능한 횟수가 최대 $N - 1$번이므로, 작업을 정확히 $N - 1$번 하는 경우만 고려해도 됩니다. 그러면 문제에서 원하는 상황은 매 작업에서 $x, y \geq 1$, $z = 0$인 것과 동치임을 보일 수 있습니다.