문제
수 N개 A1, A2, ..., AN이 주어진다. 이때, 연속된 부분 구간의 합이 M으로 나누어 떨어지는 구간의 개수를 구하는 프로그램을 작성하시오.
즉, Ai + ... + Aj (i ≤ j) 의 합이 M으로 나누어 떨어지는 (i, j) 쌍의 개수를 구해야 한다.
입력
첫째 줄에 N과 M이 주어진다. (1 ≤ N ≤ 106, 2 ≤ M ≤ 103)
둘째 줄에 N개의 수 A1, A2, ..., AN이 주어진다. (0 ≤ Ai ≤ 109)
출력
첫째 줄에 연속된 부분 구간의 합이 M으로 나누어 떨어지는 구간의 개수를 출력한다.
예제 입력 1
5 3
1 2 3 1 2
예제 출력 1
7
#3/1,2/1,2/1,2,3/2,3,1/3,1,2/1,2,3,1,2 => 7게
<나머지 합 문제 풀이의 핵심 아이디어>
# 1.(A+B) % C = ((A % C) +(B% c))
# 2. 구간 합 배열을 이용한 식 S[i] - S[j]는 원본 리스트의 j+1부터 i까지의 구간 합이다.
# => 이 두가지의 이론을 합쳐서 문제를 풀어 볼 수 있다.
<Before Coding>
<슈도 코드 작성하기>
n 입력 받기(수열의 개수)
m 입력 받기(나누어 떨어져야 하는 수)
A 입력 받기(원본 수열 저장 리스트)
S 선언하기(합 배열)
C 선언하기(같은 나머지의 인덱스를 카운트 하는 리스트)
answer 선언하기(정답변수)
for i -> 1~ n-1:
S[i] = S[i-1] + A[i] //합배열 저장
for i -> 0 ~ n-1:
remainder = S[i] % M //합 배열을 M으로 나눈 나머지 값
if(remainder == 0) 정답을 1 증가
C[remainder]의 값을 1 증가
for i-> 0 ~ m-1:
C[i](i가 나머지인 인덱스의 개수)에서 2가지를 뽑는 경우의 수를 정답에 더하기
결괏값(answer 출력)
<코드 작성하기>
import sys
input = sys.stdin.readline
n,m= map(int, input().split())
A = list(map(int, input().split()))
S = [0] * n
C = [0] * m
answer =0
S[0]=A[0]
for i in range (1,n):
S[i]= S[i-1]+A[i]
for i in range(n):
remainder = S[i]%m
if remainder ==0:
answer +=1
C[remainder] +=1
for i in range(m):
if C[i]>1:
answer +=( C[i]*(C[i]-1)) //2
print(answer)
'Study > 자료구조' 카테고리의 다른 글
스택 & 큐 & 덱 (0) | 2024.10.11 |
---|---|
투 포인터(연속된 자연수의 합 구하기)- 백준 2018번 (0) | 2024.05.16 |
구간합구하기 - 백준 11660 (0) | 2024.05.14 |
자료구조, 평균 구하기 (0) | 2024.02.24 |
자료구조, 숫자의 합 구하기 (0) | 2024.02.21 |