https://www.acmicpc.net/problem/20438
20438번: 출석체크
1번째 줄에 학생의 수 N, 졸고 있는 학생의 수 K, 지환이가 출석 코드를 보낼 학생의 수 Q, 주어질 구간의 수 M이 주어진다. (1 ≤ K, Q ≤ N ≤ 5,000, 1 ≤ M ≤ 50,000) 2번째 줄과 3번째 줄에 각각 K명
www.acmicpc.net
1. 난이도 실버2 (🥈)
2. 내가 작성한 풀이
구간합을 이용한 문제다! 나름 잘 풀었다고 생각했는데, 다른 분들이 푼 거랑 시간차이가 무려 4배가 나서 내 코드보단 수정 코드 참조하시길 추천ㅡ,,,
n,k,q,m = map(int,input().split()) #n학생수 k졸고 있는 q출석코드 m구간수
dp = [0,0,0] + [0] * (n+1) #구간합 저장
sleep = list(map(int, input().split())) #졸고 있음
connect = list(map(int, input().split())) #지환이가 연락함
connect = list(set(connect) - set(sleep)) #지환이가 연락한 사람 중 졸고 있는 사람이 있으면 뺌
result = 0
for i in range(3,n+4):
if i in sleep: #졸고 있는 학생인 경우
result+=1
dp[i] = result
continue
check = 0
for j in connect: #졸고 있지 않으며, 지환이가 연락한 번호의 배수인 경우
if i % j == 0:
check+=1
if check == 0: #졸고 있지 않지만, 연락받지 못한 경우
result+=1
dp[i] = result
for i in range(m): #범위에 맞는 구간합 구하기
a,b = map(int, input().split())
print(max(dp[:b+1]) - max(dp[:a]))
3. 수정 코드
import sys
input = sys.stdin.readline
n,k,q,m = map(int,input().rstrip().split()) #n학생수 k졸고 있는 q출석코드 m구간수
sleep = [False] * (n+3)
connect = [0] * (n+3)
for i in map(int, input().rstrip().split()): #졸고 있는 학생 체크
sleep[i] = True
for j in map(int, input().rstrip().split()):
if sleep[j]:
continue
for k in range(j, n+3, j):
if sleep[k] == False:
connect[k] = 1
prefix = [connect[0]]
for i in range(1,n+3): #구간합
prefix.append(prefix[-1] + connect[i])
for _ in range(m):
s,e = map(int, input().rstrip().split())
print(e-s+1 - (prefix[e] - prefix[s-1])) #전체에서 구간 중 출석
'🔅코딩테스트 공부🔅 > ❗백준' 카테고리의 다른 글
[백준] 1749번 점수따먹기(python)(누적합) (0) | 2023.03.02 |
---|---|
[백준] 피아노 체조(python)(누적합) (0) | 2023.03.02 |
[백준] 11659 구간 합 구하기 4(python)(누적합) (0) | 2023.03.01 |
[백준] 10986번 나머지 합(python)(누적합) (0) | 2023.03.01 |
[백준] 2670번 연속부분최대곱(python)(dp) (0) | 2023.03.01 |
댓글