2021년 9월 29일 수요일 - 여러분 21학점은 듣는게 아닌 것 같습니다...
오늘 올려볼 문제는 2531번 회전초밥 이라는 문제이다.
사진을 클릭하면 해당 문제로 이동합니다.
진짜 학교 생활 너무 힘들어서 엄청 오랜만에 블로그 쓴다..
입력 예제
첫번째 줄에 접시의 개수(n), 초밥 종류의 개수(d), 선택하려는 접시의 개수(k), 쿠폰 숫자(c)가 공백으로 구분되어 입력된다.
그 다음 n 줄에 초밥의 종류가 입력으로 들어온다.
풀이 및 코드
일단 회전 초밥은 배열의 끝과 끝이 이어져있는 경우라고도 볼 수 있다.
그렇기에 나는 크기가 접시의 개수(n)의 2배인 배열을 만들고 같은 내용을 이어서 저장하고 사용하기로 했다.
이렇게 배열을 크게 만드는 이유는 배열에 끝에 대한 처리를 편하게 하기 위함이다. 또한 선택하려는 접시의 개수(k)는 n보다 작기 때문에 2배만 하였다.
또한 중복에 대한 처리를 해줘야 하므로 현재 선택한 접시들의 개수를 저장하는 배열을 선언하여 사용한다.
어느정도 설명이 필요한 전제는 이정도이고 이제 코드를 봐보자!
풀이코드
import java.io.*;
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));
String[] input_nums = br.readLine().split(" ");
int n = Integer.parseInt(input_nums[0]), d = Integer.parseInt(input_nums[1]),
k = Integer.parseInt(input_nums[2]), c = Integer.parseInt(input_nums[3]);
// 선택한 각 초밥의 종류의 개수를 저장하는 배열(nums), 회전 초밥의 순서를 저장하는 배열(arr)
int[] nums = new int[3005], arr = new int[n * 2];
// result는 출력할 결과, diff는 각 선택한 접시의 다양성
int result = 0, diff = 0;
// 입력받기 이 때 n번째 인덱스부터 이어서 저장해주는 과정도 같이 해준다.
for(int i = 0; i < n; i++)
{
arr[i] = arr[n + i] = Integer.parseInt(br.readLine());
}
// 접시를 처음 선택하는 과정
for(int i = 0; i < k; i++)
{
// 선택하려는 초밥이 선택되지 않았다면 다양성에 1을 더함
if(nums[arr[i]]++ == 0)
{
diff++;
}
}
// 결과 초기화
result = diff;
for(int i = 0; i < n; i++)
{
// 선택한 접시중 왼쪽 접시를 뺀다
// 이때 빼고 난 후에 초밥 개수가 0이라면 다양성에 1을 뺀다.
if(--nums[arr[i]] == 0)
diff--;
// 선택한 접시중 오른쪽 접시를 더한다.
// 이때 더할 초밥 개수가 0이라면 다양성에 1을 더한다.
if(nums[arr[i + k]]++ == 0)
diff++;
// 만약 다양성이 결과보다 크다면
if(diff > result)
{
// 결과에 다양성에 대입한다.
result = diff;
}
// 쿠폰에 해당하는 초밥 개수가 0이고 결과와 다양성이 같다면
if(nums[c] == 0 && diff == result)
{
// 결과에 1을 더해준다.
result++;
}
}
bw.write(result + "\n");
bw.flush();
}
}
제출 화면
오늘은 재밌는 문제를 풀기도 했고 한동안 너무 블로그에 글을 안올려서 죄책감에 올렸다....
이 글이 도움이 되는 사람이 있기를!
'백준 문제 풀이' 카테고리의 다른 글
[BOJ / 백준] 백준 3151번 문제를 풀어보았다. (ft. Java) (1) | 2021.09.04 |
---|---|
[BOJ / 백준] 백준 1120번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.30 |
[BOJ / 백준] 백준 11399번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.29 |
[BOJ / 백준] 백준 2294번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.21 |
[BOJ / 백준] 백준 2799번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.14 |
[BOJ / 백준] 백준 3151번 문제를 풀어보았다. (ft. Java)
2021년 9월 04일 토요일 - 으윽.. 개강... 개강해....
오늘 올려볼 문제는 3151번 합이0 이라는 문제이다.
사진을 클릭하면 해당 문제로 이동합니다.
오늘은 이렇게 오래 걸릴지 몰랐던 쉬워보이는 문제를 가져왔다.
자칫하면 놓치기 쉬운 개념들이 매우 많았다
입력 예제
문제가 어려운 것에 비해서 입력은 간단하다...!
풀이 및 코드
이번 풀이는 텍스트로만은 설명하기 힘들것 같아서 이미지를 준비해왔다! 천천히 살펴보자.
그 전에 문제에 중요한 조건을 하나 보자.
힌트
입력으로 들어온 수는 같은 수더라도 다른 사람으로 취급한다는 것이다. 이 점 유의하자.
먼저 들어온 수들을 정렬해서 음수 | 0 | 양수 와 같은 형태로 생각해보자.
풀이 1
그럼 이런 범위 안에서 첫번째 수와 두번째 수를 선택할 수 있을 것이다.
첫번째 수는 음수에서만 선택하고고 두번째 수는 첫번째 수보다 1 큰 수에서 선택한다. (여기서 수는 인덱스)
풀이 2
이렇게 범위를 나누는 이유는 앞에 두 수를 찾은 뒤에 세번째 수를 이진 탐색으로 찾으면 O(n^2)의 시간복잡도로 문제를 풀 수 있기 때문이다.
여기까지는 쉽게 이해될 것이라고 생각한다.
풀이 3
자 이제 첫번째수를 모두 선택했다고 가정해보자. 그럼 모든 경우의 수를 찾은 것일까?
아니다. 0으로만 이루어진 팀에 대해서 예외처리를 해주어야한다.
예외처리는 그냥 조합 공식만 쓰면 되므로 이는 쉽다. 물론 0이 3개 이상일 때만 예외처리를 해주면 된다.
풀이 4
아까 세번째 수를 고르고 나서 결과값을 구할 때 주의해야할 점이 하나 있다.
세번째 수가 여러개 존재한다면 이에 대해서 모두 더해주어야 하기 때문이다.
그런데 이를 선형적으로 루프문을 돌려서 모두 구하게 되면 O(n^3)의 시간복잡도가 되므로 시간초과가 나게 될 것이다.
그래서 해주어야 할 것이 수의 중복 개수를 저장하고, 중복되는 수의 처음 나오는 인덱스를 저장해야 한다.
그렇다면 위, 아래 두가지 상황에 대해서 간단한 수학 공식으로 결과값을 구할 수 있게 된다.
풀이 5
이제는 코드를 봐보자! (이번 코드는 좀 많이 더럽다... 가독성이 떨어지니 주석을 잘 참고하길 바란다.)
풀이코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
public class Main {
// n 저장(글로벌로 씀)
public static int n;
// 입력 저장할 배열, 중복되는 수의 가장 처음 나오는 index 저장하는 배열, 수의 중복 개수를 저장할 배열
public static int[] arr, location, cnt;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// n 입력 받음
n = Integer.parseInt(br.readLine());
// 저장할 배열을 n + 1의 크기를 할당(처리 편하게 할려고 크게 잡는 것임)
arr = new int[n + 1];
// 위치와 중복을 저장할 배열을 200005의 크기를 할당 (배열에는 음수의 인덱스가 없으므로 10000을 0이라고 치고 계산하기 위해서 그런 것, 이것 또한 처리하기 편하게 크게 잡음)
location = new int[20005];
cnt = new int[20005];
// 0 개수를 저장함
int zero = 0;
// 입력 받음
String[] input = br.readLine().split(" ");
// int형으로 캐스팅하면서 0의 개수 및 수의 중복 개수도 저장
for(int i = 0; i < n; i++)
{
arr[i] = Integer.parseInt(input[i]);
if(arr[i] == 0)
zero++;
cnt[10000 + arr[i]]++;
}
// 배열을 1크게 잡았으므로 한 칸이 남게 되는데 기본적으로 0이 저장되어 있다. 이 상태로 정렬을 하게 되면
// 원하지 않는 0이 섞여서 저장되게 되므로 이 값을 입력으로 받을 수 없는 큰 값으로 만들어서
// 맨 오른쪽에 위치하게끔 해주는 작업이다.
arr[n] = 20000;
// 오름차순으로 정렬을 해준다.
Arrays.sort(arr);
// 중복되는 수가 처음 나오는 인덱스를 저장하기 위한 작업
int pre = arr[0];
location[10000 + arr[0]] = 0;
for(int i = 1; i < n; i++)
{
if(pre != arr[i])
{
pre = arr[i];
location[10000 + arr[i]] = i;
}
}
// 결과를 저장할 변수
long result = 0;
// 첫번째로 선택할 수는 arr[i], 음수에서만 선택한다.
for(int i = 0; i < n && arr[i] < 0; i++)
{
// 두번째로 선택할 수는 arr[j], i + 1 부터 선택한다.
for(int j = i + 1; j < n; j++)
{
// 두 값의 합이 음수라면
if(arr[i] + arr[j] < 0)
{
// 두 값의 합과 더했을 때 0이 되는 수를 구해준다.
int num = -1 * (arr[i] + arr[j]);
// 이진탐색으로 해당하는 수가 인덱스 j+1부터 배열의 끝까지 존재하는 확인한다.
if(search(num, j + 1))
{
// 존재한다면 그 수가 처음 나오는 인덱스가 3번째로 선택할 수 있는 인덱스보다 작은지 확인한다
// 작다면
if(location[10000 + num] < j + 1)
{
// (수의 중복 개수 + 수의 인덱스 위치 - 3번째로 선택할 수 있는 인덱스)를 결과값에 더해준다.
result += cnt[10000 + num] + location[10000 + num] - j - 1;
}
// 크다면
else
{
// 결과값에 수의 중복 개수를 더해준다.
result += cnt[10000 + num];
}
}
}
else
{
break;
}
}
}
// 0이 3개 이상 나왔다면
if(zero >= 3)
// 조합 공식을 사용하여 결과값에 더해준다.
result += combination(zero);
bw.write(result + "\n");
bw.flush();
}
// 조합 함수
public static long combination(int zero)
{
// (0의 개수 C 3)의 값을 리턴한다.
return zero * --zero * --zero / 1 / 2 / 3;
}
// 이진 탐색, 찾을 값과 탐색해야하는 인덱스를 파라매터로 받는다.
public static boolean search(int num, int index)
{
// index부터 탐색을 한다.
int left = index, right = n - 1, middle;
while(left <= right)
{
middle = (left + right) / 2;
if(arr[middle] == num)
{
return true;
}
else if(arr[middle] > num)
{
right = middle - 1;
}
else
{
left = middle + 1;
}
}
return false;
}
}
제출 화면
쉬워보였는데 신경쓸게 너무 많아서 많이 틀리고 조금 오래 걸렸던 문제이다...
분명 나처럼 고려해야 할 부분들을 미처 생각하지 못한 사람들이 많을 것 같아서 블로그에 올려본다.
'백준 문제 풀이' 카테고리의 다른 글
[BOJ / 백준] 백준 2531번 문제를 풀어보았다. (ft. Java) (1) | 2021.09.29 |
---|---|
[BOJ / 백준] 백준 1120번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.30 |
[BOJ / 백준] 백준 11399번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.29 |
[BOJ / 백준] 백준 2294번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.21 |
[BOJ / 백준] 백준 2799번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.14 |
[BOJ / 백준] 백준 1120번 문제를 풀어보았다. (ft. Java)
2021년 8월 30일 월요일 - 으악 개강이다!!
오늘 올려볼 문제는 1120번 문자열 이라는 문제이다.
사진을 클릭하면 해당 문제로 이동합니다.
오늘은 같은 건국대학교를 다니시는 누군지 모를 분이 푸신 문제를 가져왔다.
볼 때마다 대단한 사람들 많다고 느낌..
입력 예제
입력은 딱 봐도 알아볼 수 있는 입력이다.
풀이 및 코드
이 문제는 브루트 포스 기법을 사용해서 푸는 문제이다.
브루트 포스란 모든 경우의 수를 다 때려넣어서 정답을 구해내는 기법이다.
입력이 적고 문제를 해결하기에 마땅한 기법이 없을 때 많이 사용되는 방식이다.
백트래킹 기법과 같이 쓰이는 경우도 많다.
자 기법을 알았으니 그 기법을 어떻게 적용할지 생각해보자.
A 문자열이 항상 B 문자열보다 길이가 작으므로 A 문자열을 움직여 가장 차이가 적은 곳을 찾는다.
ex)
B: abcdef abcdef abcdef
A: abbb abbb abbb
--------------------------
차: 2 4 4
이렇게 자리만 잡아두면 A문자열 앞뒤로는 B와 같은 문자를 붙이면 되므로 2가 답이된다.
대충 감이 잡힐 것이라 믿는다..!
풀이코드
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));
// 입력 받기
String[] input = br.readLine().split(" ");
// 결과값 (문자열 최대 길이가 50이므로 그것보다 큰 숫자를 저장해둠)
int result = 55;
// B의 길이 - A의 길이 + 1 만큼 for문을 돌면서
for(int i = 0; i <= input[1].length() - input[0].length(); i++)
{
int diff = 0;
for(int j = 0; j < input[0].length(); j++)
{
// 각 자리의 차이를 구한다.
if(input[0].charAt(j) != input[1].charAt(i + j))
{
diff++;
}
}
// 해당 자리의 차이가 결과보다 작으면
result = Math.min(result, diff);
}
// 출력
bw.write(result + "\n");
bw.flush();
}
}
제출 화면
오늘은 사실 간단하게 생각하면 풀 수 있는 문제를 가지고왔다.
알고리즘 문제를 풀다 보면 시간복잡도를 생각해서 이런 무지막지한 방법은 아예 제외하고 생각하는 경우가 있는데 그런 관념을 박살내버리라고 말하는 문제인것 같다.
'백준 문제 풀이' 카테고리의 다른 글
[BOJ / 백준] 백준 2531번 문제를 풀어보았다. (ft. Java) (1) | 2021.09.29 |
---|---|
[BOJ / 백준] 백준 3151번 문제를 풀어보았다. (ft. Java) (1) | 2021.09.04 |
[BOJ / 백준] 백준 11399번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.29 |
[BOJ / 백준] 백준 2294번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.21 |
[BOJ / 백준] 백준 2799번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.14 |
[BOJ / 백준] 백준 11399번 문제를 풀어보았다. (ft. Java)
2021년 8월 29일 일요일 - 아우 블로그 쓰는거 힘두러...
오늘 올려볼 문제는 11399번 ATM 이라는 문제이다.
사진을 클릭하면 해당 문제로 이동합니다.
오늘도 채점 현황표를 보다가 한 문제 선택해서 가지고왔다!
프로젝트 때문에 알고리즘 할 시간이 점점 줄어드는 느낌..
입력 예제
입력은 딱 봐도 알아볼 수 있는 입력이다.
풀이 및 코드
이 문제는 대부분 사람들이 경험에 의해서 직관적으로 풀이에 대한 감이 올 것이라고 생각된다.
바로 중복적으로 더해지는 숫자를 낮은 수로 정하는 것 즉 오름차순 정렬을 하는 것이다.
문제를 푸는 키포인트가 나왔으니 코드를 봐보자!
풀이코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// 입력 받기
int n = Integer.parseInt(br.readLine());
String[] input = br.readLine().split(" ");
int[] arr = new int[n];
// int형으로 바꾸어 int배열에 저장하는 과정
for(int i = 0; i < n; i++)
{
arr[i] = Integer.parseInt(input[i]);
}
// 오름차수 정렬
Arrays.sort(arr);
// 결과값 저장 변수
int result = 0;
// 각 자리의 수가 더해지는 빈도는 해당 자리 수 * (전체 길이 - 해당 자리 수의 인덱스) 이다.
for(int i = 0; i < n; i++)
{
result += arr[i] * (n - i);
}
// 출력하기
bw.write(result + "\n");
bw.flush();
}
}
제출 화면
오늘은 프로젝트 때문에 바빠서 밀린 숙제하듯이 쉬운 문제를 가지고 왔다...
대부분 사람들은 그냥 풀 수 있겠지만 자라나는 코린이 분들을 위해서 적는 것이라고 합리화를 해본다...
'백준 문제 풀이' 카테고리의 다른 글
[BOJ / 백준] 백준 3151번 문제를 풀어보았다. (ft. Java) (1) | 2021.09.04 |
---|---|
[BOJ / 백준] 백준 1120번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.30 |
[BOJ / 백준] 백준 2294번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.21 |
[BOJ / 백준] 백준 2799번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.14 |
[BOJ / 백준] 백준 2493번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.02 |
[BOJ / 백준] 백준 2294번 문제를 풀어보았다. (ft. Java)
2021년 8월 21일 토요일 - 이번에도 오랜만에 백준 풀이를 올린다..!
오늘 올려볼 문제는 2294번 동전 2 라는 문제이다.
사진을 클릭하면 해당 문제로 이동합니다.
오늘은 채점 현황표를 보다가 한 문제 선택해서 가지고왔다!
문제 고르는 것도 문제 푸는 것만큼 어려운 듯..
입력 예제
입력은 딱 봐도 알아볼 수 있는 입력이다.
풀이 및 코드
이 문제의 알고리즘 분류가 다이나믹 프로그래밍으로 되어있는데 나는 처음에 이를 무시하고 직관대로 풀었다!
그 결과...
제출 화면
값이 큰 동전부터 차례대로 동전의 개수를 구한다고 해서 최소가 아닐 수 있다는 것을 깨닫고... 다이나믹 프로그래밍을 통해서 문제를 해결했다...
자세한 설명은 코드를 보면서 하자!
풀이코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
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));
// 입력받기
String[] input_num = br.readLine().split(" ");
// int로 바꾸기
int n = Integer.parseInt(input_num[0]), k = Integer.parseInt(input_num[1]);
// 동전의 가치를 저장할 배열, dp를 위한 배열 2개를 선언(dp배열의 크기는 넉넉하게 잡아두는 것이 좋다.)
// dp는 동전의 개수를 저장한다고 생각하면 된다.
int[] arr = new int[n], dp = new int[150000];
// 입력받아서 동전의 가치를 배열에 저장
for(int i = 0; i < n; i++)
{
arr[i] = Integer.parseInt(br.readLine());
}
// dp배열을 큰 수로 채운다. (동전 개수의 최솟값을 구하는 것이기 때문에 큰 수를 저장해두면 편하다.)
Arrays.fill(dp, Integer.MAX_VALUE);
// 입력받은 동전의 가치가 정렬되어 있지 않을 수 있기 때문에 정렬을 시행해준다.
Arrays.sort(arr);
// 작은 가치를 가진 동전부터 k가 될 때까지 동전의 개수를 dp에 저장하면서 센다.
// 이 때 더욱 적은 동전으로 해당 값을 표현할 수 있으면 적은 개수를 저장한다.
for(int i = 0; i < n; i++)
{
// arr[i]에 해당하는 가치는 arr[i] 동전 하나로 표현 가능하므로 해당 dp를 동전 1개로 설정해둔다.
dp[arr[i]] = 1;
// k만큼 dp를 살펴본다.
for(int j = 0; j <= k; j++)
{
// 만약 dp[j]가 큰수가 아니라면 (즉 입력받은 동전들로 만들 수 있는 값이라면)
if(dp[j] != Integer.MAX_VALUE)
{
// (현재 j값 + 동전의 가치)에 저장되어있는 동전의 개수와 와 (현재 j값)에 저장되어 있는 동전의 개수 + 1 중 더 작은 값을 dp[j + arr[i]]에 저장한다.
dp[j + arr[i]] = Math.min(dp[j + arr[i]], dp[j] + 1);
}
}
}
// 만약 dp[k]가 큰수라면 (동전들로 만들 수 없는 값이라면)
if(dp[k] == Integer.MAX_VALUE)
{
// -1을 출력한다.
bw.write("-1");
}
// 아니라면
else
{
// dp[k]를 출력한다.
bw.write(dp[k] + "\n");
}
bw.flush();
}
}
제출 화면
오늘 문제는 자칫하면 잘못 풀 가능성이 큰 문제를 가져왔다.
항상 직관을 믿지말고 데이터를 믿자!
'백준 문제 풀이' 카테고리의 다른 글
[BOJ / 백준] 백준 1120번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.30 |
---|---|
[BOJ / 백준] 백준 11399번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.29 |
[BOJ / 백준] 백준 2799번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.14 |
[BOJ / 백준] 백준 2493번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.02 |
[BOJ / 백준] 백준 17298번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.30 |
[BOJ / 백준] 백준 2799번 문제를 풀어보았다. (ft. Java)
2021년 8월 14일 토요일 - 정말 오랜만에 백준 풀이를 올린다..!
오늘 올려볼 문제는 2799번 블라인드 라는 문제이다.
사진을 클릭하면 해당 문제로 이동합니다.
오늘은 내 코드를 본 사람이 푼 문제 중에서 아무거나 하나 골라서 풀어보았다!
문제 고르는 고민을 덜어주셔서 감사해요!
입력 예제
입력은 텍스트로 만들어낸 그래픽 같은 느낌의 입력이다!
사람이 보기에는 깔끔하니 좋지만 프로그래밍 하는 입장에서는 딱히 좋지는 않다는 것...
풀이 및 코드
이 문제는 워낙 간단하게 풀 수 있는 문제니 바로 코드를 보자!
풀이코드
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));
// 입력 받기
String[] input_nums = br.readLine().split(" ");
// int로 바꾸기
int m = Integer.parseInt(input_nums[0]), n = Integer.parseInt(input_nums[1]);
// 블라인드의 형태 5가지 각각의 개수를 저장하는 배열
int[] result = new int[5];
// 처음 ##### 부분을 입력받는 부분, split 구문과 for문에 방해되기 때문에 입력만 받고 사용하지는 않는다.
br.readLine();
// m번 만큼 진행
for(int i = 0; i < m; i++)
{
// 각 층의 창문들이 어떤 형태를 하고 있는지 저장하는 배열 (형태를 저장하는 것임, 개수 저장 X)
int[] blinds = new int[n];
for(int j = 0; j < 4; j++)
{
// 입력받고 #을 기준으로 split한다. 이 때 처음 창문은 인덱스 1번 부터 있다. 즉 배열의 크기는 n + 1!
String[] input = br.readLine().split("#");
for(int k = 0; k < n; k++)
{
// 만약 이 창문에 *이 포함되어 있다면
if(input[k + 1].contains("*"))
{
// 해당하는 창문에 형태를 1 올려줌
blinds[k]++;
}
}
}
// ##### 부분 처리해주는 구문
br.readLine();
for(int k = 0; k < n; k++)
{
// 각 형태에 개수를 1씩 올려줌
result[blinds[k]]++;
}
}
for(int i = 0; i < 5; i++)
{
bw.write(result[i] + " ");
}
bw.flush();
}
}
제출 화면
오늘 문제는 간단한 문제로 가지고 왔다...
물론 C언어 같이 제공하는 메소드가 적은 언어에서는 그리 간단한 문제는 아니지만 이런 자바와 같은 언어에서는 매우 쉬운 문제였다..!
요즘 개인적으로 진행하는 프로젝트 때문에 바빠서 글을 자주 못 올렸는데 그래도 1주일에 하나는 올려야 할 것 같아서 올리는 중이다..! ㅋㅋㅋ
시간이 되면 프로젝트 준비하는 과정도 정리해서 올려야겠다.
'백준 문제 풀이' 카테고리의 다른 글
[BOJ / 백준] 백준 11399번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.29 |
---|---|
[BOJ / 백준] 백준 2294번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.21 |
[BOJ / 백준] 백준 2493번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.02 |
[BOJ / 백준] 백준 17298번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.30 |
[BOJ / 백준] 백준 1043번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.26 |
[BOJ / 백준] 백준 2493번 문제를 풀어보았다. (ft. Java)
2021년 8월 2일 월요일 - 벌써 8월이 됐네..
오늘 올려볼 문제는 2493번 탑 라는 문제이다.
사진을 클릭하면 해당 문제로 이동합니다.
오늘은 백준을 둘러보다가 골드문제를 하나 발견해서 가지구 왔다.
슬슬 문제 찾는 레파토리가 떨어져간다...
입력 예제
입력은 매우 단순한 문제이다.
풀이 및 코드
이 문제는 스택을 잘 사용해야 하는 문제다.
문제를 간략히 설명해보자면
- 입력으로 각 탑의 높이가 들어온다. (같은 높이의 탑은 없다.)
- 각 탑은 탑의 꼭대기에서 왼쪽으로 신호를 보낸다.
- 2에서 보낸 신호를 받을 수 있는 센서는 각 탑의 기둥에 부착되어있다. (탑의 높이만큼 길게 부착되어있다는 것)
- 이 때 가장 먼저 신호를 받는 탑의 위치가 어디인지 출력한다.
그러므로 스택에 각 탑의 위치(인덱스)를 넣고 비교하는 과정을 통해서 이 문제를 해결할 수 있다!
아직 헷갈릴 수 있으니 코드를 봐보자!
풀이코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(br.readLine());
String[] input_arr = br.readLine().split(" ");
int[] arr = new int[n];
// 각 탑의 인덱스를 저장할 스택
Stack<Integer> s = new Stack<Integer>();
for(int i = 0; i < n; i++)
{
// string으로 받은 입력을 int형으로 바꿔주는 작업
arr[i] = Integer.parseInt(input_arr[i]);
// 만약 스택이 비었다면 (신호를 받을 수 있는 탑이 없다면)
if(s.isEmpty())
{
// 0을 출력한다. (신호를 못 받는 경우 0 출력)
bw.write("0 ");
}
// 스택이 비어있지 않다면
else
{
// 아래 과정 반복
while(true)
{
// 스택이 비었다면
if(s.isEmpty())
{
// 0 출력하고 반복문 벗어나기
bw.write("0 ");
break;
}
// 스택에 들어있는 탑의 위치(인데스)에 있는 탑의 높이가 현재 탑의 높이보다 크다면
if(arr[s.peek()] > arr[i])
{
// 스택에 들어있는 탑의 위치 + 1을 출력하고 반복문을 벗어난다.
// 1 더해주는 것은 인덱스와 문제에서 원하는 답과의 차이 때문에 해준다.
bw.write((s.peek() + 1) + " ");
break;
}
// 스택에 들어있는 탑의 위치(인데스)에 있는 탑의 높이가 현재 탑의 높이보다 크지 않다면
else
{
// 스택에서 pop해준다.
s.pop();
}
}
}
// 항상 스택에 현재 탑의 위치(인덱스)를 add해준다.
s.add(i);
}
bw.flush();
}
}
제출 화면
오늘 문제는 스택을 생각하지 못한다면 굉장히 풀기 힘든 문제이다.
사실 바로 전에 올렸던 문제와 굉장히 흡사한 문제였기에 이 블로그를 봤던 사람이라면 쉽게 풀었을 것이다.
이 블로그를 보는 사람이 거의 없다는 점이 문제긴 하지만...
'백준 문제 풀이' 카테고리의 다른 글
[BOJ / 백준] 백준 2294번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.21 |
---|---|
[BOJ / 백준] 백준 2799번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.14 |
[BOJ / 백준] 백준 17298번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.30 |
[BOJ / 백준] 백준 1043번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.26 |
[BOJ / 백준] 백준 1987번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.24 |
[BOJ / 백준] 백준 17298번 문제를 풀어보았다. (ft. Java)
2021년 7월 30일 금요일 - 건강 검진 처음 해봄!
오늘 올려볼 문제는 17298번 오큰수 라는 문제이다.
사진을 클릭하면 해당 문제로 이동합니다.
오늘은 건컴 후배님이 푸신 문제들을 둘러보다가 찾은 문제를 가지고 왔다!
형님 보고 계시나요??
입력 예제
입력은 매우 단순한 문제이다.
풀이 및 코드
이 문제는 스택을 사용하는 것이 가장 중요한 포인트이다.
풀이를 간단히 설명해보자면
- 스택에는 배열의 인덱스를 저장한다.
- 스택이 비어있지 않을 경우에는 아래의 과정을 진행한다.
- 스택의 들어있는 인덱스에 해당하는 값보다 현재 인덱스의 해당하는 값이 클 경우 스택에서 인덱스를 pop하고 pop한 인덱스 부분에 현재 인덱스의 해당하는 값을 저장한다.
- 스택의 들어있는 인덱스에 해당하는 값보다 현재 인덱스의 해당하는 값이 크지 않을 경우 이 과정을 벗어난다.
- 또한 스택이 비어있는 경우에도 이 과정을 벗어난다.
- 스택이 비어있을 경우에는 그냥 해당하는 인덱스를 저장한다.
- 위 과정이 모두 끝나면 스택이 비워지지 않을 때까지 스택에 있는 인덱스를 꺼내서 인덱스 부분에 -1을 저장한다.
위에서 설명을 간단히 하느라 조금 헷갈리는 부분이 있을 수도 있을 것 같다... (특히 해당하는 인덱스와 저장하는 부분의 괴리)
그러니 코드를 봐보자!
풀이코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// n 입력 받음
int n = Integer.parseInt(br.readLine());
// 배열 입력 받음
String[] input_arr = br.readLine().split(" ");
// 최종적으로 출력할 숫자들을 저장하는 배열 (위에서 설명한 저장하는 곳이 이 배열이다.)
int[] result = new int[n];
// 스택
Stack<Integer> s = new Stack<Integer>();
for(int i = 0; i < n; i++)
{
while(true)
{
// 스택이 비워져 있다면 break;
if(s.isEmpty())
break;
// 스택에 들어있는 인덱스를 입력받은 배열에 접근하여 값을 가져옴, 그 값이 현재 for문 i에 해당하는 값보다 작으면
if(Integer.parseInt(input_arr[s.peek()]) < Integer.parseInt(input_arr[i]))
{
// result배열에 스택에 들어있던 인덱스를 pop하고 그 인덱스에 현재 for문 i에 해당하는 값을 저장한다.
result[s.pop()] = Integer.parseInt(input_arr[i]);
}
// 아니라면 break;
else
{
break;
}
}
// 위 과정과 상관없이 현재 인덱스는 스택에 항상 추가해준다.
s.add(i);
}
// 스택에 값이 남아있다면
while(!s.isEmpty())
{
// 스택에 들어있던 인덱스를 pop하고 그 인덱스에 -1을 저장한다.
result[s.pop()] = -1;
}
// result 배열을 출력한다.
for(int i = 0; i < n; i++)
{
bw.write(result[i] + " ");
}
bw.flush();
}
}
제출 화면
오늘 문제는 스택을 생각하지 못한다면 굉장히 풀기 힘든 문제이다.
2중 for문을 사용하면 시간복잡도가 O(n^2)이 되어버리기 때문에 최대 입력이 1,000,000인 이 문제에서는 시간초과가 분명히 날 것이다.
이런 문제들을 볼 때마다 자료구조 공부가 얼마나 중요한지 깨닫게 되는거 같다.
'백준 문제 풀이' 카테고리의 다른 글
[BOJ / 백준] 백준 2799번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.14 |
---|---|
[BOJ / 백준] 백준 2493번 문제를 풀어보았다. (ft. Java) (0) | 2021.08.02 |
[BOJ / 백준] 백준 1043번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.26 |
[BOJ / 백준] 백준 1987번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.24 |
[BOJ / 백준] 백준 2578번 문제를 풀어보았다. (ft. Java) (0) | 2021.07.21 |