본문 바로가기
컴퓨터/Python, Java

[Java]기본형 변수 크기 및 범위

by stubborngastropod 2023. 6. 17.
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

댓글