CodeUp 1084 : [기초-종합] 빛 섞어 색 만들기 - Java

ayleen·2022년 2월 8일
0

문제 : https://codeup.kr/problem.php?id=1084&rid=0

문제 설명

빨강(red), 초록(green), 파랑(blue) 빛을 섞어
여러 가지 빛의 색을 만들어 내려고 한다.

빨강(r), 초록(g), 파랑(b) 각각의 빛의 개수가 주어질 때,
(빛의 강약에 따라 0 ~ n-1 까지 n가지의 빛 색깔을 만들 수 있다.)

주어진 rgb 빛들을 다르게 섞어 만들 수 있는 모든 경우의 조합(r g b)과
총 가짓 수를 계산해보자.


예시
int i, j, k, c=0;
int r, g, b;
scanf("%d%d%d”, &r, &g, &b);

for(i=0; i<r; i++)
for(j=0; j<g; j++)
for(k=0; k<b; k++)
{
printf("%d %d %d\n", i, j, k);
c++;
}

printf("%d ", c);


입력

빨녹파(r, g, b) 각 빛의 강약에 따른 가짓수(0 ~ 128))가 공백을 사이에 두고 입력된다.
예를 들어, 3 3 3 은 각 색깔 빛에 대해서 그 강약에 따라 0~2까지 3가지의 색이 있음을 의미한다.


출력

만들 수 있는 rgb 색의 정보를 오름차순(계단을 올라가는 순, 12345... abcde..., 가나다라마...)으로
줄을 바꿔 모두 출력하고, 마지막에 그 개수를 출력한다.


입력 예시

2 2 2


출력 예시

0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
8




내 코드

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		String input = sc.nextLine();
		String[] num = input.split(" ");
		int r = Integer.parseInt(num[0]);
		int g = Integer.parseInt(num[1]);
		int b = Integer.parseInt(num[2]);
		int cnt = 0;
		for(int i = 0; i < r; i++) {
			for(int j = 0; j < g; j++) {
				for(int k = 0; k < b; k++) {
					System.out.printf("%d %d %d%n", i, j, k);
					cnt++;
				}
			}
		}
		System.out.println(cnt);
		
	}

}
  1. 입력 예시에 공백이 있기 때문에 nextLine();으로 값을 받았다.
    테스트해보니 그냥 next();로 받을 경우 '2 2 2'를 입력했을 때 input값에 그냥 '2'만 저장되었다.
  2. 공백을 없애주고 입력받은 값을 따로 저장하기 위해 split을 이용해 공백을 기준으로 나눠서 배열에 담았다.
  3. 배열에 들어있는 값을 각각 r, g, b에 담아줬다.
  4. 마지막으로 경우의 수를 출력해야하기 때문에 cnt값을 초기화로 설정해주고 for문을 돌때마다 1씩 증가시켜주고 fot문 밖에서 출력해줬다.

출력된 결과

2 2 2를 입력해서 문제에 나온 출력예시와 같은 값을 출력했다.
코드업에 코드를 제출하니 시간초과라고 뜨는데 게시판을 보니 나만 그런건 아닌가보다.
인줄 알았는데 틀렸단다 제길

구글링해보자





BufferedReader / BufferedWriter

버퍼를 이용해서 읽고 쓰는 함수
입출력의 효율이 좋아진다.

버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달된다.
버퍼를 사용하는 입력은 키보드의 입력이 있을 때마다 한 문자씩 버퍼로 전송된다.

하드디스크는 원래 속도가 느리다고한다. 키보드의 키를 누르는 즉시 바로 전달되어 빠를 것 같지만 하드뿐만 아니라 키보드와 모니터같은 외부 장치와의 데이터 입출력은 생각보다 시간이 오래걸린다.

버퍼링 없이 키보드가 눌릴 때마다 정보를 목적지로 바로 이동시키는 것보다 중간에 버퍼를 두어 한 번에 묶어 보내는 것이 더 효율적이고 빠른 방법이라고 한다.

예를 들자면, 쓰레기가 생길때마다 하나하나 밖에 내다버리는 것과 집안의 쓰레기통에 모아놨다가 꽉 차면 한 번에 밖에 내다 버리는 것과 비슷하다.


Scanner vs BufferedReader

Scanner는 띄어쓰기와 개행문자를 경계로 입력값을 인식하기 때문에 따로 가공할 필요가 없다.
반면에 BufferedReader는 개행만 경계로 인식하고 입력 받은 데이터가 String형태로 고정되기 때문에 원하는 타입으로 데이터를 가공하는 작업이 필요하다. 하지만 Scanner에 비해 상대적으로 빠르다.

Scanner와 BufferedReader의 속도차이를 잘 보여주는 예시
10,000,000개의 0~1023 범위의 정수를 한 줄씩 읽고 입력으로 받은 정수의 합을 출력하는 프로그램을 구현할 때 수행 시간

버퍼 사이즈도 Scanner가 1024char인데에 비해 BufferedReader는 8192char(16,384byte)이기 때문에 많은 데이터를 입력받아야 할때에는 BufferedReader를 이용하면 좋다.

또한 BufferedReader는 동기화되기 때문에 멀티쓰레드 환경에서 안전하다고 한다.
(멀티쓰레드에 대해 또 공부해야겠다.)


BufferedReader 사용법

// 콘솔에서 입력받을 경우
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();

// 파일에서 입력받을 경우
FileReader fr = new FileReader("FileName.java");
BufferReader br_f = new BufferReader(fr);

// 입출력이 끝난 후 닫아주기
br.close();

// 파일을 한 줄 한 줄 읽어서 출력
String line = "";
for(int i = 1; (line = br_f.readLine()) != null; i++){
	System.out.print(line);
}

위와 같은 방법으로 선언한다.
입력은 readLine();이라는 메소드를 사용한다.
String으로 입력값이 고정되어있기 때문에 다른 타입으로 입력받고싶다면 형변환이 필요하다.

BufferedReader를 통해 받아온 데이터는 개행문자단위(Line단위)로 나누어진다.
만약 공백단위로 가공하고자 하면 따로 작업이 필요하다.

그리고 반드시 예외처리를 해줘야한다.
try/catch나 throws IOException을 이용한다.(대부분 후자를 이용한다고 한다.)

StringTokenizer

StringTokenizer st = new StringTokenizer(br.readLine());

StringTokenizer의 nextToken()함수를 이용하면 readLind()을 통해 입력받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.

아니면 String.split()을 이용해 공백단위로 끊어 저장하여 사용하면 된다.

BufferedWriter

일반적으로 출력을 할 때, System.out.println();을 이용한다.
하지만 많은 양의 출력을 해야할 때에는 입력과 동일하게 버퍼를 사용하는 것이 좋다.

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("hello");       // 출력
bw.newLine();			 // 개행
bw.write("world\n");  	 // 개행과 함께 출력
bw.flush();				 // 남아있는 데이터를 모두 출력(출력해서 없애기, clean)
bw.close();				 // 스트림닫기





코드 수정

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));
		String input = br.readLine();
		StringTokenizer token = new StringTokenizer(input);
		int r = Integer.parseInt(token.nextToken());
		int g = Integer.parseInt(token.nextToken());
		int b = Integer.parseInt(token.nextToken());
		int cnt = 0;
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		for(int i = 0; i < r; i++) {
			for(int j = 0; j < g; j++) {
				for(int k = 0; k < b; k++) {
					bw.write(i + " " + j + " " + k + "\n");
					cnt++;
				}
			}
		}
		bw.write(String.valueOf(cnt));
		bw.flush();
		bw.close();
	}

}


참고
1084 빛 섞어 색 만들기 : https://kyungahstory.tistory.com/160
BufferedRead : https://jhnyang.tistory.com/92 | https://rlakuku-program.tistory.com/33 StringTokenizer : https://jhnyang.tistory.com/398
profile
asdf

0개의 댓글