728x90
https://www.acmicpc.net/problem/10986
10986번: 나머지 합
수 N개 A1, A2, ..., AN이 주어진다. 이때, 연속된 부분 구간의 합이 M으로 나누어 떨어지는 구간의 개수를 구하는 프로그램을 작성하시오. 즉, Ai + ... + Aj (i ≤ j) 의 합이 M으로 나누어 떨어지는 (i, j)
www.acmicpc.net
10986. 나머지 합
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[] arr = new int[N];
int[] arr2 = new int[M];
int res = 0;
st = new StringTokenizer(br.readLine());
arr[0] = Integer.parseInt(st.nextToken()) % M;
if (arr[0] == 0) res += 1;
arr2[arr[0]]++;
for (int i = 1; i < N; i++) {
arr[i] = (Integer.parseInt(st.nextToken()) + arr[i - 1]) % M;
if (arr[i] == 0) res++;
arr2[arr[i]]++;
}
for (int i = 0; i < M; i++) {
res += arr2[i] * (arr2[i] - 1) / 2;
}
bw.write(String.valueOf(res));
bw.close();
}
}
평화롭게 구간합 문제 풀던 중, 아무리 봐도 맞는 이 코드가 계속 틀렸다고 뜨는 것이다. 너무 답답해서 gpt한테 물어봐도 문제 없다고 하는 상황... 답안 코드랑 유심히 비교하다보니 틀린점을 발견할 수 있었다.
단순히 값들만 보면 int 범위 내에서 해결이 가능하지만, 구간 합을 구했을 때 int의 범위를 훌쩍 넘길 수 있으므로 구간합을 정리하는 배열에서는 long 자료형을 써줘야 한다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
long[] arr = new long[N]; // 여기는 int 사용 가능
long[] arr2 = new long[M];
long res = 0;
st = new StringTokenizer(br.readLine());
arr[0] = Integer.parseInt(st.nextToken()) % M;
if (arr[0] == 0) res += 1;
arr2[(int) arr[0]]++;
for (int i = 1; i < N; i++) {
arr[i] = (Integer.parseInt(st.nextToken()) + arr[i - 1]) % M;
if (arr[i] == 0) res++;
arr2[(int) arr[i]]++;
}
for (int i = 0; i < M; i++) {
res += arr2[i] * (arr2[i] - 1) / 2;
}
bw.write(String.valueOf(res));
bw.close();
}
}
이런식으로 입력값을 long 자료형으로 받아준다. int로 해줘도 되는 부분이 있지만 빡센 최적화가 필요치 않다면 long을 해줘도 괜찮은 것 같다. long 자료형을 인덱스로 할 때는 int 자료형이 와야 하므로 (int)를 통해 형변환을 해준다.
파이썬에서 자바로 넘어오며 가장 처음 만났던 자료형 범위에 대해 처음으로 실전 경험을 했던 것 같다. 정리를 해두고 두고두고 참고해야겠다.
boolean | false, true | 1 byte |
char | 0000 ~ ffff | 2 byte |
byte | -128 ~ 127 | 1 byte |
short | -32,768 ~ 32,767 | 2 byte |
int | -2,147,483,648 ~ 2,147,483,647 | 4 byte |
long | -2^64 ~ 2^64 - 1 | 8 byte |
float | 1.4E-45 ~ 3.4E38 | 4 byte |
double | 4.9E-324 ~ 1.8E308 | 8 byte |
728x90
'컴퓨터 > Python, Java' 카테고리의 다른 글
[Java]BufferedReader, BufferedWriter 사용법 (0) | 2023.06.14 |
---|
댓글