개발자 Saaad

[JAVA] 백준 3단계(반복문) 문제 풀이 본문

알고리즘 문제풀이/백준

[JAVA] 백준 3단계(반복문) 문제 풀이

Saaad 2025. 1. 15. 15:46

(2739번) 구구단 

  • N을 입력받은 뒤, 구구단 N단을 출력하는 프로그램을 작성하시오. 출력 형식에 맞춰서 출력하면 된다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

        for (int i = 1; i <= 9; i++) {
            System.out.println(N + " * " + i + " = " + N * i);
        }
    }
}
  • 간단하게 입력받은 숫자를 반복문을 돌며 index를 곱해주며 출력해주면 된다.

(10950번) A + B - 3

  • 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 아이디어
        // for문을 사용하여 입력받은 횟수만큼 반복하며 배열에 담아놨다가 또 한번 반복문을 통해 출력한다
        
        // for문 반복 횟수
        int N = Integer.parseInt(br.readLine());
        int[] arr = new int[N];

        for (int i = 0; i < N; i++) {
            String str = br.readLine();

            int A = Integer.parseInt(str.split(" ")[0]);
            int B = Integer.parseInt(str.split(" ")[1]);
        
            arr[i] = A + B;
        }
        for(int i = 0; i < N; i++) {
            System.out.println(arr[i]);
        }
    }
}
  • for문을 이용해 반복횟수 N만큼 반복하며 숫자를 더하여 배열에 값을 할당한 뒤, 배열을 순회하며 값을 출력한다.

(8393번) 합

  • n이 주어졌을 때, 1부터 n까지 합을 구하는 프로그램을 작성하시오.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 문제
        /* 
           n이 주어졌을 때, 1부터 n까지 합을 구하는 프로그램을 작성하시오.
         */
        
        // 입력
        //첫째 줄에 n (1 ≤ n ≤ 10,000)이 주어진다.

        // 출력 
        // 1부터 n까지 합을 출력한다.

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

        int sum = 0;

        for (int i = 1; i <= N; i++) {
            sum += i;
        }
        System.out.println(sum);
    }
}
  • 반복문을 1부터 N까지 반복하며 index를 sum에 계속 더해주면 된다.

 

반복문 없이 풀이

  • 그냥 넘어가려고 했는데 문제 설명에 "물론 반복문 없이도 풀 수 있습니다"가 써있다. 풀어보자
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 문제
        /* 
           n이 주어졌을 때, 1부터 n까지 합을 구하는 프로그램을 작성하시오.
         */
        
        // 입력
        //첫째 줄에 n (1 ≤ n ≤ 10,000)이 주어진다.

        // 출력 
        // 1부터 n까지 합을 출력한다.

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

        int sum = (N*(N + 1)) / 2;

        System.out.println(sum);
    }
}
  • 생각해보니 이건 그냥 중학교 수학때 배운 공식으로 풀면 되는 것이었다.
  • 등차수열의 합 공식을 이용하면 된다.

근데 소요 시간은 똑같다.. ? 반복문 안돌았는데 너무 간단한 코드라 차이가 안나나봄

 


(25304번) 영수증

  • 준원이는 저번 주에 살면서 처음으로 코스트코를 가 봤다. 정말 멋졌다. 그런데, 몇 개 담지도 않았는데 수상하게 높은 금액이 나오는 것이다! 준원이는 영수증을 보면서 정확하게 계산된 것이 맞는지 확인해보려 한다.
    영수증에 적힌,
    - 구매한 각 물건의 가격과 개수
    - 구매한 물건들의 총 금액
    을 보고, 구매한 물건의 가격과 개수로 계산한 총 금액이 영수증에 적힌 총 금액과 일치하는지 검사해보자.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 입력
        // 첫째 줄에는 영수증에 적힌 총 금액 X가 주어진다.      
        // 둘째 줄에는 영수증에 적힌 구매한 물건의 종류의 수 N이 주어진다.

        // 이후 
        // N개의 줄에는 각 물건의 가격 a와 개수 
        // n가 공백을 사이에 두고 주어진다.

        // 출력 
        // 구매한 물건의 가격과 개수로 계산한 총 금액이 영수증에 적힌 총 금액과 일치하면 Yes를 출력한다. 
        // 일치하지 않는다면 No를 출력한다.

        // 총 금액 X
        int totalPrice = Integer.parseInt(br.readLine());

        // 구매한 물건의 종류의 수 N
        int N = Integer.parseInt(br.readLine());

        for(int i = 0; i < N; i++) {
            String[] input = br.readLine().split(" ");

            int price = Integer.parseInt(input[0]);
            int count = Integer.parseInt(input[1]);

            totalPrice -= price * count;
        }

        if(totalPrice == 0) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }
    }
}
  • 총 금액을 입력받고 각 물건의 가격과 구입한 갯수를 입력받는다.
  • 총 금액에서 각 물건의 가격과 갯수를 곱한 값을 반복문에서 차감하여 0이 되는지 확인해보면 된다.
  • 물건의 가격과 갯수를 곱한 값을 모두 뺐을 때 0이라면 총 가격이 일치하는 것

(25314번) 코딩은 체육과목입니다

  • 오늘은 혜아의 면접 날이다. 면접 준비를 열심히 해서 앞선 질문들을 잘 대답한 혜아는 이제 마지막으로 칠판에 직접 코딩하는 문제를 받았다. 혜아가 받은 문제는 두 수를 더하는 문제였다. C++ 책을 열심히 읽었던 혜아는 간단히 두 수를 더하는 코드를 칠판에 적었다. 코드를 본 면접관은 다음 질문을 했다. “만약, 입출력이 바이트 크기의 정수라면 프로그램을 어떻게 구현해야 할까요?”
  • 혜아는 책에 있는 정수 자료형과 관련된 내용을 기억해 냈다. 책에는 long int 4바이트 정수까지 저장할 수 있는 정수 자료형이고 long long int 바이트 정수까지 저장할 수 있는 정수 자료형이라고 적혀 있었다. 혜아는 이런 생각이 들었다. “int 앞에 long을 하나씩 더 붙일 때마다 4바이트씩 저장할 수 있는 공간이 늘어나는 걸까? 분명 long long long int 12바이트, long long long long int 16바이트까지 저장할 수 있는 정수 자료형일 거야!” 그렇게 혜아는 당황하는 면접관의 얼굴을 뒤로한 채 칠판에 정수 자료형을 써 내려가기 시작했다.
  • 혜아가 N바이트 정수까지 저장할 수 있다고 생각해서 칠판에 쓴 정수 자료형의 이름은 무엇일까?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        // 입력
        // 첫 번째 줄에는 문제의 정수 N이 주어진다.

        // 출력 
        // 혜아가 N바이트 정수까지 저장할 수 있다고 생각하는 정수 자료형의 이름을 출력하여라.

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

        if (N % 4 != 0){
            System.out.println("입력 형식을 확인해주세요");
            return;
        }

        for (int i = 0; i < N/4; i++){
            System.out.print("long ");
        }
        System.out.println("int");
     }
}
  • 문제가 엄청 장황한데.. 그냥 long 한 개당 4바이트라 생각하고 반복해주면 된다.
  • 입력 검증을 위해 if문을 추가했다. 만약 4의 배수가 아니라면 프로그램은 종료된다.
  • 4의 배수를 입력했다면 4로 나눈 몫만큼 "long "을 반복하여 출력 후 마지막에 int를 출력한다.

(15552번) 빠른 A+B

  • A + B를 수행하는데 입력 방법과 출력 방법을 기존의 Scanner나 System.out.println() 을 쓰지 않고,
    시간 초과가 나지 않도록 BufferedReader, BufferedWriter 를 이용하여 풀어보는 문제이다.
  • 시간 제한 1초
  • 수행시간을 비교해보도록 하겠다.

1. 기존의 Scanner + System.out.println()

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 입력
        int N = sc.nextInt(); // 테스트케이스 개수

        for (int i = 0; i < N; i++) {
            int A = sc.nextInt();
            int B = sc.nextInt();
            // 각 결과를 즉시 출력
            System.out.println(A + B);
        }

        sc.close(); // Scanner 자원 해제
    }
}

 

2. Scanner + StringBuilder + System.out.println()

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 입력
        int N = sc.nextInt(); // 테스트케이스 개수
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < N; i++) {
            int A = sc.nextInt();
            int B = sc.nextInt();
            sb.append(A + B).append("\n"); // 결과를 StringBuilder에 저장
        }

        // 출력
        System.out.print(sb.toString());

        sc.close(); // Scanner 자원 해제
    }
}

 

3. BufferedReader + System.out.println()

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 입력
        int N = Integer.parseInt(br.readLine()); // 테스트케이스 개수

        for (int i = 0; i < N; i++) {
            String[] input = br.readLine().split(" "); // A와 B를 공백으로 분리
            int A = Integer.parseInt(input[0]);
            int B = Integer.parseInt(input[1]);
            // 결과를 즉시 출력
            System.out.println(A + B);
        }
    }
}

 

4. BufferedReader + BufferedWriter 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

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));

        // 입력
        // 첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다.
        // 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다.

        // 출력
        // 각 테스트케이스마다 A+B를 한 줄에 하나씩 순서대로 출력한다.

        int N = Integer.parseInt(br.readLine());
        int[] result = new int[N];

        for (int i = 0; i < N; i++) {
            String[] input = br.readLine().split(" ");
            int A = Integer.parseInt(input[0]);
            int B = Integer.parseInt(input[1]);
            result[i] = A + B;
        }

        for (int i = 0; i < N; i++) {
            bw.write(result[i] + "\n");
        }
        bw.flush();
        bw.close();
    }
}

 

5. BufferedReader + BufferedWriter + StringBuilder

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

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));
        StringBuilder sb = new StringBuilder();

        // 첫 줄에 테스트케이스의 개수 N이 주어집니다.
        int N = Integer.parseInt(br.readLine());

        // N개의 줄에 대해 처리
        for (int i = 0; i < N; i++) {
            String[] input = br.readLine().split(" "); // A와 B를 공백으로 분리
            int A = Integer.parseInt(input[0]);
            int B = Integer.parseInt(input[1]);

            // 계산 결과를 StringBuilder에 저장
            sb.append(A + B).append("\n");
        }

        // 결과를 BufferedWriter로 출력
        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }
}

 

(메모리 + 시간) 순위 정리 

1. BufferedReader + BufferedWriter + StringBuilder : 279,808KB, 884ms

2. BufferedReader + BufferedWriter : 296,176KB, 876ms

3. Scanner + StringBuilder + System.out.println() : 318,692KB, 2172ms

 

4. BufferedReader + System.out.println() : 시간 초과

5. Scanner + System.out.println() : 시간 초과

 

결론

  • Scanner와 System.out.println() 을 조합하여 사용하는 것은 간단한 프로그램을 작성하는데는 문제가 없지만
    대용량 처리를 해야할 때는 많은 메모리와 코드 수행 시간이 길어진다는 것을 알 수 있었다.
  • BufferedReader + BufferedWriter + StringBuilder 조합을 사용할 때 가장 효율적이다.
  • StringBuilder를 사용하지 않고 BufferedReader + BufferedWriter 를 사용했을 때 미세하게 코드 수행 시간은 
    짧았다.
  • Scanner + StringBuilder + System.out.println() 조합을 사용했을 때는 테스트에 통과는 했으나
    아주 많은 메모리와 긴 코드 수행 시간을 가지는 것을 보면 효율적이진 않은 것 같다.
  • Scanner + StringBuilder + BufferedWriter 조합도 해봤는데.. 테스트는 통과하나 무려 
    322396KB, 2080ms라는 끔찍한 결과를 보여줬다.


(11021번) A+B-7

  • 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

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));
        StringBuilder sb = new StringBuilder();

        int N = Integer.parseInt(br.readLine());
        int[] result = new int[N];

        for (int i = 0; i < N; i++) {
            String[] input = br.readLine().split(" ");
            int A = Integer.parseInt(input[0]);
            int B = Integer.parseInt(input[1]);
            result[i] = A + B;
            sb.append("Case #" + (i+1) + ": " + result[i]).append("\n");
        }

        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }
}


(11022번) A+B-8

  • 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

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));
        StringBuilder sb = new StringBuilder();

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

        for (int i = 0; i < N; i++) {
            String[] input = br.readLine().split(" ");
            int A = Integer.parseInt(input[0]);
            int B = Integer.parseInt(input[1]);
            sb.append("Case #" + (i+1) + ": " + A + " + " + B + " = " + (A + B)).append("\n");
        }

        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }
}
  • 그냥 조금 출력 형식이 바뀌는 것 정도

(2438번) 별 찍기 - 1

  • 첫째 줄에는 별 1개, 둘째 줄에는 별 2개, N번째 줄에는 별 N개를 찍는 문제
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

        for (int i = 1; i <= N; i++) {
            for(int j = 0; j < i; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}
  • 반복문을 중첩하여 해결

(2439번) 별 찍기 - 2

  • 첫째 줄에는 별 1개, 둘째 줄에는 별 2개, N번째 줄에는 별 N개를 찍는 문제
    하지만, 오른쪽을 기준으로 정렬한 별(예제 참고)을 출력하시오.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

        for (int i = 1; i <= N; i++) {
            for (int j = 0; j < (N - i); j++) {
                System.out.print(" ");
            }
            for (int j = 0; j < i; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}
  • 똑같이 별 찍기 문제이지만 조금 형태가 다르다. 앞에 공백을 추가하고 좌우 대칭으로 별 계단을 만드는 예제
  • for문을 중첩하여 첫번째 for문에서 N번의 줄을 출력할 수 있도록 하였다
  • 두 번째 for문에서는 공백을 출력하기 위해 N-i 를 하여 N-1, (N-1)-1....0 이런 식으로 공백을 출력하도록 함
  • 세 번째 for문은 순서대로 별을 1,2..N 출력할 수 있도록 하였다. 

(10952번) A + B - 5

  • 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

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));
        StringBuilder sb = new StringBuilder();

        /*  입력
            입력은 여러 개의 테스트 케이스로 이루어져 있다.
            각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
            입력의 마지막에는 0 두 개가 들어온다.
         */

         /* 출력
           각 테스트 케이스마다 A+B를 출력한다.
          */
  
        while (true) { 
            String str = br.readLine();
            int A = Integer.parseInt(str.split(" ")[0]);
            int B = Integer.parseInt(str.split(" ")[1]);
            
            if (A == 0 && B == 0) {
                break;
            }
            sb.append(A + B).append("\n");
        }
        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }
}
  • 이전 문제랑 다르게 입력 횟수를 정하는 것이 아니라 0 0 을 입력 받으면 종료하는 것이 조건이기 때문에
    while문을 이용해 문제를 해결
  • StringBuilder를 이용해 배열을 선언해놓지 않고 모아놨다가 한번에 BufferedWriter를 이용해 출력
  • 반드시 bw.flush() 를 통해 할당 끊기
  • if문을 이용해 while문을 break를 이용해 종료

(10951번) A + B - 4

  • 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

BufferedReader를 이용한 방법

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));
        StringBuilder sb = new StringBuilder();

        String str;
        // EOF 처리
        while ((str = br.readLine()) != null) {
            StringTokenizer st = new StringTokenizer(str, " ");
            int A = Integer.parseInt(st.nextToken());
            int B = Integer.parseInt(st.nextToken());
            sb.append(A + B).append("\n");
        }

        // 출력
        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }
}
  • 이 문제에서 애를 좀 먹었다 EOF? 를 이용해서 입력을 중단하고 결과까지 출력해야하는 문제이다.
  • MAC의 경우 Ctrl + D 를 통해, Window는 Ctrl + Z 로 EOF 처리를 해줄 수 있다.
  • JAVA에서 BufferedReader의 경우 null을 반환하기 때문에 while문에서 null 을 이용해 EOF 처리를 하였다.

Scanner를 이용한 방법

import java.util.Scanner;
 
public class Main {
	public static void main(String args[]){
		
		Scanner in=new Scanner(System.in);
			
		while(in.hasNextInt()){
		
			int a=in.nextInt();
			int b=in.nextInt();
			System.out.println(a+b);
		
		}	
		in.close();
	}
}
  • 입력값이 존재하지 않으면 프로그램은 종료된다.
  • Scanner에서는 hasNaxtInt(), hasNext() 를 이용하여 EOF를 처리할 수 있다.
  • Scanner의 메소드들의 경우 더이상 읽을 데이터가 없으면 아래 사진과 같이 NoSuchElementException을 던지게 된다.

https://st-lab.tistory.com/40

Scanner 의 메소드인 hasNext() 를 통해 예외를 처리할 수 있다. 데이터를 입력받지 않은 경우 EOF 취급을 하기 때문이다.

참고한 내용
https://st-lab.tistory.com/40

 

[백준] 10951번 : A+B - 4 - JAVA [자바]

https://www.acmicpc.net/problem/10951 10951번: A+B - 4 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오. www.acmicpc.net 문제 간단한 문제지만 의외로 종료시점을 몰라 틀리는 경우들이 많

st-lab.tistory.com