앳코더 ABC 457 후기
tkd0711 · 2026. 5. 9.
Polaris.AI Programming Contest 2026 (AtCoder Beginner Contest 457)
https://atcoder.jp/contests/abc457
- 날짜: 2026-05-09 (Sat)
- 결과: A~D AC, 1000점
- A: 2:08
- B: 5:01
- C: 28:19, 3틀
- D: 69:58, 1틀
1. 전체 느낌
이번 대회는 결과만 보면 A~D를 풀어서 1000점이었다.
A, B는 무난하게 처리했고,
C에서 크게 말렸다.
D는 한 번 틀렸지만, 방향 자체는 바로 잡아서 결국 해결했다.
체감상 가장 아쉬웠던 건 C였다.
예전에 cnt 변수를 long으로 안 둬서 틀린 적이 있어서,
그 뒤로 누적 변수는 꽤 신경 쓰고 있었다.
그런데 이번에는 아예 입력받는 K부터 long으로 처리하지 않아서 틀렸다.
즉, 누적 변수만 조심할 게 아니라
처음 변수 선언부터 자료형을 제대로 봐야 한다는 걸 다시 배운 대회였다.
2. A, B – 무난한 시작
A와 B는 크게 문제 없이 해결했다.
A는 2분대, B는 5분대에 처리했고,
초반 흐름은 나쁘지 않았다.
이번 대회가 아쉽게 느껴지는 건
초반 문제 때문이 아니라 C에서 자료형 문제로 시간을 크게 쓴 것 때문이다.
3. C – Long Sequence: K부터 long이어야 했다
문제 요약
여러 개의 수열 A_i가 있고,
각 수열을 C_i번 반복해서 하나의 긴 수열 B를 만든다.
이때 실제로 B를 만들 수는 없으므로,K번째 원소가 어느 수열의 어느 위치에 해당하는지 찾아야 하는 문제였다.
접근
풀이 자체는 어렵지 않았다.
각 수열마다 기여하는 길이는
C_i * L_i
이고,
이 값을 앞에서부터 누적하다가 K가 들어가는 구간을 찾으면 된다.
해당 구간을 찾은 뒤에는
그 수열 안에서 몇 번째 원소인지 나머지 연산으로 구하면 된다.
즉 구조는:
- 각 수열의 길이
L_i저장 - 반복 횟수
C_i저장 C_i * L_i를 누적K가 현재 구간 안에 들어오면 위치 계산- 해당 원소 출력
이었다.
실수한 부분
문제는 자료형이었다.
C_i는 최대 10^9이고,
수열 길이와 곱한 값의 누적은 int 범위를 훨씬 넘을 수 있다.
따라서
K- 현재까지 누적한 길이
C_i * L_i
는 전부 long이어야 했다.
그런데 처음에는 K를 int로 읽었다.
이 때문에 런타임 에러가 계속 났고,
나는 그 원인을 나머지 연산 쪽 문제라고 생각해서 식을 계속 고쳤다.
하지만 진짜 원인은 더 앞에 있었다.
입력받는 순간부터 자료형이 틀렸던 것이다.
교훈
예전에는 cnt 변수를 long으로 안 해서 틀린 적이 있었다.
그래서 이후로 누적 변수는 조심하려고 했다.
그런데 이번에는 그보다 더 앞단계인
입력 변수 선언부터 long이어야 하는 경우를 놓쳤다.
앞으로는 다음 조건이 보이면 처음부터 long을 의심해야 한다.
K가 위치를 뜻하는 경우- 전체 길이가 반복 횟수와 곱해지는 경우
C_i * L_i같은 곱셈이 있는 경우- 실제 배열을 만들 수 없을 정도로 길이가 커지는 경우
이번 C는 풀이를 몰라서 틀린 문제가 아니라,
자료형 확인을 늦게 해서 시간을 잃은 문제였다.
4. D – Raise Minimum: 최소의 최대는 이분탐색
문제 요약
수열 A가 있고,
최대 K번 연산할 수 있다.
한 번의 연산에서는 인덱스 i를 골라A_i에 i를 더할 수 있다.
이때 최종적으로 만들 수 있는min(A_i)의 최댓값을 구하는 문제였다.
접근
문제를 보자마자
“최소값의 최대”라는 형태가 보였다.
이런 문제는 보통
정답을 직접 구하기보다,
어떤 값
X이상으로 모든 원소를 만들 수 있는가?
를 판정하고,
그 X를 이분탐색하면 된다.
그래서 목표값 num을 정하고,
각 A_i를 num 이상으로 만들기 위해 필요한 연산 횟수를 계산했다.
A_i < num일 때 필요한 횟수는:
ceil((num - A_i) / i)
이다.
모든 원소에 대해 필요한 연산 횟수를 더해서
그 값이 K 이하이면 num은 가능하고,
아니면 불가능하다.
한 번 틀린 이유
처음 판정 함수에서는 필요한 연산 횟수 cnt를 끝까지 계속 더했다.
cnt += plz;
그런데 num이 매우 크면
필요한 연산 횟수의 합이 long 범위를 넘을 수 있다.
사실 판정 함수에서 필요한 건
정확한 총합이 아니라
K를 넘는지 아닌지
뿐이다.
그래서 정답 코드에서는 다음처럼 고쳤다.
cnt += plz;
if (cnt > k) break;
K를 넘는 순간 더 계산할 필요가 없고,
이렇게 하면 오버플로도 막을 수 있다.
느낀 점
D는 방향 자체는 좋았다.
“최소의 최대”를 보고 바로 이분탐색을 떠올렸고,
판정 함수도 거의 맞게 세웠다.
다만 누적값이 커질 수 있는 경우에는
끝까지 더하지 말고 기준을 넘는 순간 멈춰야 한다는 점을 다시 확인했다.
5. 이번 대회에서 좋았던 점
1) A, B는 무난했다
초반 문제에서 크게 흔들리지 않았다.
2) C에서 말렸지만 D까지 복구했다
C에서 자료형 문제로 시간을 크게 썼지만,
거기서 완전히 무너지지 않고 D를 해결했다.
3) D의 방향을 잘 잡았다
“최소의 최대”를 보고 이분탐색으로 들어간 판단은 좋았다.
6. 아쉬웠던 점
1) C에서 K를 int로 읽은 것
이번 대회에서 가장 큰 실수였다.
누적 변수는 조심하고 있었지만,
정작 입력받는 변수 자체를 long으로 봐야 한다는 걸 놓쳤다.
2) 자료형 문제를 나머지 연산 문제로 착각한 것
런타임 에러가 났을 때
원인을 잘못 짚어서 시간을 더 썼다.
앞으로는 나머지 식을 고치기 전에
입력 자료형과 누적 자료형부터 먼저 확인해야 한다.
3) D 판정 함수에서 누적합을 끝까지 더한 것
판정 함수에서는 필요한 기준을 넘는 순간 멈춰도 된다.
이걸 더 빨리 떠올렸으면 한 번 틀리지 않았을 것 같다.
7. 다음 목표
K가 위치나 길이를 뜻하면 처음부터long으로 읽기- 반복 횟수와 길이의 곱은 무조건
1L *붙이기 - 누적 길이, 누적 횟수, 필요한 연산 수는 전부
long의심하기 - 판정 함수에서는 기준을 넘는 순간 바로 중단하기
- 런타임 에러가 나면 나머지 식보다 먼저 자료형 확인하기
한 줄 정리
ABC 457은 C에서
K를 처음부터long으로 처리하지 않아 크게 말렸지만,
D에서 이분탐색으로 복구해 1000점까지 가져온 대회였다.