Java - 알고리즘

백준 JAVA - 3단계 for 활용하기 (2) (feat. 별 찍기, x보다 작은 수)

TerianP 2021. 10. 8.
728x90

2021.09.29 - [알고리즘 공부] - JAVA - 3단계 for 활용하기 (1) (feat.Buffer, StringTokenizer, String.split 사용)

이번에는 for문 알고리즘 문제 2편입니다(1편은 위에 링크로)

 

지난 글에 이어서 2742번부터 10871번까지 풀어보았다.

다만 문제 유형에 맞춰 2742 ~ 11022 번까지와 2438 ~ 10871 번으로 나누어 적도록 하겠다.

 

1. 2742 ~ 11022 까지 풀이!!

여기 문제는 이전 문제를 풀었다면 크게 문제없을 정도의 난이도! 입력-출력의 반복이라는 점과 BufferedWriter 로 입력받았을 때 나누는 방법만 알면 크게 문제 될 것은 없어보인다.

package baekJoon;

import java.io.*;

public class Q10_3 {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		Q_2742();
		Q_11021();
		Q_11022();

	}
	
	static void Q_2742() throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
	
		int N = Integer.parseInt(br.readLine());
		
		for(int i=N; i>=1; i--) {
			bw.write(i+"\n");
		}
		
		br.close();
		bw.flush();
		bw.close();
	}
	
	static void Q_11021() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int t = Integer.parseInt(br.readLine());
		int i=0;
		String num="";
		int result=0;

		for(i=1; i<=t; i++) {
			num = br.readLine();

			String[] str = num.split(" ");


			result = Integer.parseInt(str[0])+Integer.parseInt(str[1]); // 입력받은 값 나눠서 더하기

			bw.write("Case #"+i+": "+result);
			bw.newLine();
		}
		br.close();
		bw.flush();
		bw.close();
	}

	static void Q_11022() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int t = Integer.parseInt(br.readLine());
		int i=0;
		String num="";
		int result=0;

		for(i=1; i<=t; i++) {
			num = br.readLine();

			String[] str = num.split(" ");


			result = Integer.parseInt(str[0])
					+Integer.parseInt(str[1]);

			bw.write("Case #"+i+": "+str[0]+" + "+str[1]+" = "+result);
			bw.newLine();
		}
		br.close();
		bw.flush();
		bw.close();
	}

}

 

2. 2438 ~ 10871 까지 풀이!

여기는 별찍기 2438 문제와 10871 번 문제는 크게 어렵지 않게 넘어갔는데, 별찍기 2439번 문제에서 상당히 고민했다. 물론 이렇게 고민한거는 내가 이중 for문에 대해서 제대로 이해하지 못했기 때문...이라고 생각한다. 해당 문제를 어떻게 풀었는지는 아래에 더 적도록 하겠다.

package baekJoon;

import java.io.*;

public class Q10_3 {

	public static void main(String[] args) throws IOException {
		
		Q_2438();
		Q_2439(); 
		Q_10871();
	}
	

	static void Q_2438() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int n = Integer.parseInt(br.readLine());

		
		for(int i=1; i<=n; i++) { // 바깥 for 문은 몇 줄을 반복할 것인지(행)
			for(int k=1; k<=i; k++) { // 안쪽 for 문은 몇 칸을 반복할 것인지(열)
				bw.write("*");
			}
			bw.newLine();
		}
		br.close();
		bw.flush();
		bw.close();
	}

	static void Q_2439() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int n = Integer.parseInt(br.readLine());

//		방법1.println		
//		for(int i=1; i<=n; i++) { 
//			for(int j=n; j>i; j--) {
//				System.out.print(" ");
//			}
//			for(int k=1; k<=i; k++) { // 열
//				System.out.print("*");
//			}
//			System.out.println();
//		}
		
//		방법2. buffer     
		for(int i=1; i<=n; i++) { 
			for(int j=n; j>i; j--) {
				bw.write(" ");
			}
			for(int k=1; k<=i; k++) { // 열
				bw.write("*");
			}
			bw.newLine(); // 빈줄 추가
		}
		

		
		br.close();
		bw.flush();
		bw.close();
	}
	
	static void Q_10871() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		String N = br.readLine();
		String[] X = N.split(" "); // 입력받은 2개의 값을 공백 기준으로 분리
		
		int a = Integer.parseInt(X[0]); // 첫번째 입력받은 값 int 로 변환
		int b = Integer.parseInt(X[1]); // 입력받은 두번째 값을 int 로 변환
		
		String num = br.readLine(); 
		String[] result = num.split(" ");
		

		for(int i=0; i<a; i++) {
			if(b>Integer.parseInt(result[i])) { // 두번째 입력받은 값을 기준으로 result[i] 값을 비교
				bw.write(result[i]+" "); // 두번째 값보다 작으면 result[i] 출력
			}
		}

		br.close();
		bw.flush();
		bw.close();
	}
}



2438 결과
*
**
***
****
*****

2439 결과
    *
   **
  ***
 ****
*****

 

별찍기를 활용한 이중 for 문에 대해 요약하자면 이중 for 문에서 바깥 for 문은 행, 안쪽 for 문은 열 을 의미한다고 생각하면 편하다. 더 구체적으로는 바깥 for문 = 행 = 세로크기 = row, 안쪽 for문 = 열 = 가로크기=col 이라고 생각하면 된다.

 

이를 생각하면서 별찍기 2438 문제를 보자

	static void Q_2438() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int n = Integer.parseInt(br.readLine());

		for(int i=1; i<=n; i++) { // 행 = 세로크기
			for(int k=1; k<=i; k++) { // 열 = 가로크기
				bw.write("*");
			}
			bw.newLine();
		}
		br.close();
		bw.flush();
		bw.close();
	}
    

<출력 결과>
(출력 결과를 보면 함수 좌표의 모양이 일반적인 수학의 그것과 다른데 이는 컴퓨터에서 출력하면 첫째줄부터 출력되기 때문이라고 생각하면 된다)
y1 *
y2 *  *
y3 *  *  *
y4 *  *  *  *
y5 *  *  *  *  *
   x1 x2 x3 x4 x5

 

1. 출력되어야하는 결과를 생각해보면 y 값은 1에서 n까지이다. 마찬가지로 x 값은 1~n까지이다. 여기서 함수 좌표의 모양이 일반적인 수학의 그것과 다른데 이는 컴퓨터에서 출력하면 첫째줄부터 출력되기 때문이라고 생각하면 된다. 따라서 첫째줄이자 맨 윗줄이 y1 이 되는 것이다.

2. 이렇게 한 뒤에 생각해보면 y 값이 증가함에 따라서 x값도 증가하는 것을 볼 수 있다. 정확히는 y1 일 때 x1 , y2 일 때 x2 이런식으로 증가한다. 이걸 정리하자면 y가 n번째 행 일 때 x는 y개가 찍히게 된다.

3. 최종적으로 바깥 for 문의 i값은 입력받은 n 을 기준으로 하고, 안쪽 for 문의 k 값은 해당 y 만큼만 * 을 찍는다.

for(int i=1; i<=n; i++) { // 행 = 세로크기 = row = 입력받은 n 만큼 증가함
	for(int k=1; k<=i; k++) { // 열 = 가로크기 = col
	bw.write("*");
	}
bw.newLine();
}

 

별찍기 2439 문제는 2438 문제의 응용이다.

for(int i=1; i<=n; i++) { // 행
	for(int j=n; j>i; j--) { // 열1
		bw.write(" "); // 공백은 행이 늘어날수록 감소!!
	}
	for(int k=1; k<=i; k++) { // 열2
		bw.write("*"); // * 은 행이 늘어날수록 증가!!
	}
	bw.newLine();
}
		

<결과 출력>
// 공백은 감소, * 은 증가
    *
   **
  ***
 ****
*****

결국 중요한 것은 공백은 감소하고 * 은 증가하는 것을 아는것이다.

1. 정확히는 y가 한줄한줄 증가 할 수록 공백으로 이루어진 칸은 감소하고 * 로 이루어진 칸은 증가하는 것이다(어쩌면 y 값에 따라서 x값이 2개라고 생각하면...편하려나?)

2. 이에 따라서 행을 이루는 바깥 for 문안에 안쪽 for 문을 2개를 두어 각각 증가하는 모양 감소하는 모양으로 넣어두면 이번 문제를 쉽게 풀 수 있다.

 

번외로 BufferedWriter 을 사용했을 때와 println 을 사용했을 때의 출력 시간 차이는 약 2배정도...확실히 buffer이 빠르다.

위가 buffer 아래가 println

 

 

 

※ 다만 알아두어야 할 점은 함수로 x 값 y 값해서 푸는거는 본인이 해당 문제를 풀면서 고민하다가 얻어낸 방법입니다. 기존 이중 for문에 대해서 완벽히 이해를 못했기 때문에 이러한 방법을 생각해냈다고 봐서...그냥 이렇게 생각할 수도 있구나 하고 봐주셨으면 합니다.

댓글