728x90

[문제 링크]

 

1015번: 수열 정렬

P[0], P[1], ...., P[N-1]은 0부터 N-1까지(포함)의 수를 한 번씩 포함하고 있는 수열이다. 수열 P를 길이가 N인 배열 A에 적용하면 길이가 N인 배열 B가 된다. 적용하는 방법은 B[P[i]] = A[i]이다. 배열 A가 주

www.acmicpc.net

import java.util.*;

public class Main {
	static int n;
    static int[] A, B, P;
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) {
        input();
        solve();
        System.out.println(sb.toString());
    }

    private static void solve() {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (A[j] == B[i] && P[j] == -1) {
                    P[j] = i;
                    break;
                }
            }
        }

        for (int i : P) {
            sb.append(i + " ");
        }
    }

    private static void input() {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        A = new int[n];
        B = new int[n];
        P = new int[n];

        for (int i = 0; i < n; i++) {
            A[i] = sc.nextInt();
            B[i] = A[i];
        }

        Arrays.fill(P, -1);
        Arrays.sort(B);
    }
}

이번 문제는 입력과 출력값이 왜 예시처럼 나오는지 이해하는데에 시간이 좀 걸렸다. 정확하게 이해한 것인지 아닌지 확인하기 위해 다른 블로그를 참고하였고, 그림을 통해 이해하면 훨씬 쉽게 이해할 수 있음을 깨닫고 그림으로 그려봤다.

 

🔝A를 바르게 정렬한 배열을 B로 두고 A의 값과 일치한 값을 B에서 찾아 인덱스를 반환하여 P의 값으로 준다.

즉, A 배열의 값과 B배열의 값과 인덱스로 배열 P를 찾아낼 수 있는 것이다. 

 

위의 그림을 똑같이 코드로 구현한다면 아래와 같다.

A의 배열 값을 입력받아 생성하고, B 배열도 그대로 값을 받은 후 정렬한다. 
P 배열은 -1 값으로 초기화한다.
이후 A 배열의 값과 B 배열의 값이 일치하고 P 배열의 값이 초기화되어 있을 때, P 배열의 값으로 B 배열의 인덱스를 준다.
728x90

'💻코딩 > 💡Baekjoon' 카테고리의 다른 글

[백준] 1021 회전하는 큐  (1) 2023.12.13
[백준] 1016 제곱 ㄴㄴ 수  (0) 2023.05.02
[백준] 1014 컨닝  (0) 2023.02.04
[백준] 1013 Contact  (0) 2023.01.16
[백준] 1012 유기농 배추  (2) 2023.01.13
728x90

[문제 링크]

 

1014번: 컨닝

최백준은 서강대학교에서 “컨닝의 기술”이라는 과목을 가르치고 있다. 이 과목은 상당히 까다롭기로 정평이 나있기 때문에, 몇몇 학생들은 시험을 보는 도중에 다른 사람의 답지를 베끼려 한

www.acmicpc.net

 

import java.util.*;

public class Main {
	static int dp[][]; //자리
	static boolean visited[][]; //컨닝 가능한 자리
	static int N,M;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		int T = sc.nextInt();

		for(int i = 0; i < T; i++) {
			N = sc.nextInt();
			M = sc.nextInt();
			dp = new int[1<<N][M];

			for(int j = 0; j < (1<<N); j++) {
				Arrays.fill(dp[j], -1); //-1로 배열 초화화
			}

			visited = new boolean[N][M];
			for(int j = 0; j < N; j++) {
				String input = sc.next();
				for(int k = 0; k < M; k++) {
					if(input.substring(k, k+1).equals("x"))
						visited[j][k] = true;
				}
			}
			int result = getDP(0,0);
			System.out.println(result);
		}
	}

	static int getDP(int n, int m) {
		if(m==M) return 0; //모든 줄을 체크한 경우
		if(dp[n][m] != -1) return dp[n][m];
		int num = n;
		
		for(int i = 0; i < N; i++) {
			if ((n & (1<<i)) > 0){
				num |= (1<<(i+1));
				num |= (1<<(i -1));
			}
		}

		int res = getDP(0, m+1); //아무도 앉히지 않고 다음 줄로 넘어가는 경우
		for(int i = 1; i < (1<<N); i++) {
			if((i&num) > 0) continue; //나올 수 없는 경우의 수 제외
			int count = 0;
			boolean isAvail = true;

			for(int j = 0; j < N && isAvail; j++) {
				if((i & (1<<j)) > 0) { //해당 자리에 학생이 앉아있는 경우
					count++;
					if (visited[j][m]) isAvail = false; //장애물이 있을 시 = 나올 수 없는 경우의 수
				}
			}
			if(!isAvail) continue; //
			res = Math.max(res, getDP(i, m+1) + count);
		}
		return dp[n][m] = res;
	}
}

 

이번 문제는 아래의 블로그를 보며 해결하였으며, 공부가 더 필요한 것 같다😓

 

[백준 1014][자바] 컨닝

https://www.acmicpc.net/problem/1014 1014번: 컨닝 문제 최백준은 서강대학교에서 “컨닝의 기술”이라는 과목을 가르치고 있다. 이 과목은 상당히 까다롭기로 정평이 나있기 때문에, 몇몇 학생들은 시험

pigranya1218.tistory.com

참고를 위해 블로그 링크를 삽입했다.

728x90

'💻코딩 > 💡Baekjoon' 카테고리의 다른 글

[백준] 1015 수열 정렬  (0) 2023.05.18
[백준] 1016 제곱 ㄴㄴ 수  (0) 2023.05.02
[백준] 1013 Contact  (0) 2023.01.16
[백준] 1012 유기농 배추  (2) 2023.01.13
[백준] 1010 다리 놓기  (0) 2023.01.11
728x90

[문제 링크]

 

1013번: Contact

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 전파를 표현하는, { 0, 1 }만으로 이루어진 문자열이 공백 없이 주어진다. 문자열 길이는 (1 ≤

www.acmicpc.net

import java.util.*;

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

		String Vega = "(100+1+|01)+";
		int T = sc.nextInt();

		for(int i = 0; i < T; i++) {
			String N = sc.next();

			if(N.matches(Vega)) {
				System.out.println("YES");
			} else {
				System.out.println("NO");
			}
		}
	}
}

정규표현식을  접하기 전에 문제를 봤을 때 집합의 규칙을 어떻게 코드로 작성해야 할지 막막했다. 

혼자 끙끙 거리다 결국 개발자의 영원한 친구, 구글링 도움을 받기로 결정하고 구글링을 한 결과, 거의 모든 분들이 정규표현식을 사용했다. (이런 신세계를...)

그렇다. 나는 이 문제를 통해 정규표현식을 처음 접했다‼

 

정규표현식의 Matcher 클래스를 사용하여 '(100+1+|01)+'을 패턴으로 주고, 패턴과 일치 또는 불일치를 출력하도록 했다.

이때, 패턴은 string 타입이므로 입력받는 수 N 또한, string 타입으로 받아야 한다.

 

 

 

자세한 정규표현식의 설명은 JAVA 카테고리를 참고하도록 하자.

728x90

'💻코딩 > 💡Baekjoon' 카테고리의 다른 글

[백준] 1016 제곱 ㄴㄴ 수  (0) 2023.05.02
[백준] 1014 컨닝  (0) 2023.02.04
[백준] 1012 유기농 배추  (2) 2023.01.13
[백준] 1010 다리 놓기  (0) 2023.01.11
[백준] 1009 분산처리  (0) 2023.01.10
728x90

[문제링크]

 

1012번: 유기농 배추

차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 

www.acmicpc.net

import java.util.*;

public class Main {
	static int M;
	static int N;
	static int K;

	static int[] dr = {-1, 1, 0, 0};
	static int[] dc = {0, 0, -1, 1};

	static int[][] arr;
	static boolean[][] visit;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		int T = sc.nextInt();
		for(int i = 0; i < T; i++) {
		
			M = sc.nextInt();	
			N = sc.nextInt();	
			K = sc.nextInt();

			arr = new int[M][N];
			visit = new boolean[M][N];

			for(int j = 0; j < K; j++) {
				int x = sc.nextInt();
				int y = sc.nextInt();

				arr[x][y] = 1;
			}

			int count = 0;

			for(int j = 0; j<M; j++) {
				for(int z = 0; z<N; z++) {
					if(arr[j][z] == 1 && !visit[j][z]) {
						dfs(j,z);
						count++;
					}
				}
			}
			System.out.println(count);
		}		
	}


public static void dfs(int r, int c) {
	visit[r][c] = true;

	for(int i = 0; i < 4; i++){
		int nr = r + dr[i];
		int nc = c + dc[i];

		if(nr >= 0 && nc >= 0 && nr < M && nc < N) {
			if(arr[nr][nc] == 1 && !visit[nr][nc]) {
				dfs(nr, nc);
			}
		}
	}
    } 
}

🔝DFS 알고리즘을 활용한 코드이다.

 

위 문제는 배추의 위치를 입력 받아 값을 1로 주고 인접한 배추로 지렁이가 방문했는지 확인하기 위해 깊이 우선 탐색 알고리즘인 DFS를 활용했다. 

                   
              1 1 1
        1     1 1 1
    1 1 0     1 1 1
        1          
        1          
  1                
1 1                

문제의 이해를 돕기 위해 표를 그려봤다. 위 표의 경우 지렁이는 5마리가 필요하다. 왜냐하면 인접한 배추로는 옮겨다닐 수 있으므로 상하좌우에 배추가 심어져있다면 지렁이를 더 필요로 하지 않는다. (이동 가능하므로) 하지만 상하좌우 모두 배추가 심어져 있지 않은 0이라면 지렁이를 필요로 하므로 count의 값을 +1 해주는 것이다. 

 

즉, 배추밭의 크기를 입력받고, 배추가 심어진 좌표를 배열에 값을 1로 하여 저장한다. 이후, 해당 좌표의 값이 1이고 visit이 false라면 dfs 메소드를 호출하여 visit을 true로 바꿔준 후, 상화좌우의 값을 확인하고 count를 +1한다. 

최종적으로 count의 값을 출력하면 필요한 지렁이의 수를 알 수 있다.

728x90

'💻코딩 > 💡Baekjoon' 카테고리의 다른 글

[백준] 1014 컨닝  (0) 2023.02.04
[백준] 1013 Contact  (0) 2023.01.16
[백준] 1010 다리 놓기  (0) 2023.01.11
[백준] 1009 분산처리  (0) 2023.01.10
[백준] 1008 A/B  (0) 2023.01.09
728x90

[문제링크]

 

1010번: 다리 놓기

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.

www.acmicpc.net

import java.util.*;

public class Main {
	static int[][] dp = new int[30][30];

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		int T = sc.nextInt();
		
		StringBuilder sb = new StringBuilder();
        
		for(int i = 0; i < T; i++) {
		
			int N = sc.nextInt();	
			int M = sc.nextInt();	
		
			sb.append(combi(M, N)).append('\n');
		}
		
		System.out.println(sb);
		
	}
	
	static int combi(int n, int r) {
		
		if(dp[n][r] > 0) {
			return dp[n][r]; 
		}

		if(n == r || r == 0) {
			return dp[n][r] = 1;
		}

		return dp[n][r] = combi(n - 1, r - 1) + combi(n - 1, r);
	}
}

🔝조합을 사용한 코드이다.

n, m개의 사이트를 입력받고, 중복되지 않게 다리를 놓을 수 있으므로 m개의 사이트에서 n개의 사이트의 수를 정하는 경우의 수를 구하면 되는 간단한 문제이다.

 

이는 조합을 뜻하며 재귀호출 방식을 사용하여 경우의 수를 계산하고 출력하도록 했다.

이때, 값을 저장하기 위해 StringBuilder를 사용했다.

728x90

'💻코딩 > 💡Baekjoon' 카테고리의 다른 글

[백준] 1013 Contact  (0) 2023.01.16
[백준] 1012 유기농 배추  (2) 2023.01.13
[백준] 1009 분산처리  (0) 2023.01.10
[백준] 1008 A/B  (0) 2023.01.09
[백준] 1007 벡터 매칭  (1) 2023.01.07
728x90

[문제링크]

 

1009번: 분산처리

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 정수 a와 b가 주어진다. (1 ≤ a < 100, 1 ≤ b < 1,000,000)

www.acmicpc.net

import java.util.*;

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

		int T = sc.nextInt();

		for(int j=0;j<T;j++) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			int res = 1;
			
			for (int i=0;i<b;i++) {
                res = (res * a) % 10;
            }
			if(res==0) res=10;
			System.out.println(res);
		}
	}
}

🔝분산처리 코드이다.

 

이 문제는 a^b을 10으로 나눈 나머지를 구하면 되는 간단한 문제이다.

하지만, pow 함수를 사용할 시 b의 값이 크면 결과를 계산할 수 없는 매우 큰 숫자가 되므로 다른 방법을 사용해야 한다.

 

그래서 생각한 방식은 1의 자리 수만을 가지고 계산을 하는 것이다.

9^1 9^2 9^3
9 81 729
9 1 9

위의 표를 보면 쉽게 이해할 수 있다. 9의 제곱은 81이다. 이를 10으로 나눈 나머지는 1이고, 1에 9를 곱한 값이 9의 세제곱의 1의 자리수가 되는 것이다. 즉, 9이다.

 

1의 자리만을 활용하여 계산할 경우 큰 값도 빠르게 수행 가능하다. 

 

이때, 나머지가 0인 경우 0으로 출력하는 것이 아니라 10으로 출력하도록 주의해야 한다.

728x90

'💻코딩 > 💡Baekjoon' 카테고리의 다른 글

[백준] 1012 유기농 배추  (2) 2023.01.13
[백준] 1010 다리 놓기  (0) 2023.01.11
[백준] 1008 A/B  (0) 2023.01.09
[백준] 1007 벡터 매칭  (1) 2023.01.07
[백준] 1005 ACM Craft  (0) 2023.01.06
728x90

[문제 링크]

 

1008번: A/B

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

www.acmicpc.net

 

import java.util.*;

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

        double a = sc.nextDouble();
        double b = sc.nextDouble();
        
        System.out.println(a/b);
    }  
}

 

오늘의 문제는 매우 간단한 문제이다. 

A와 B의 값을 double 타입으로 입력 받아서 나눗셈을 하면 된다. 이때, double 타입을 사용한 이유는  절대오차 또는 상대오차가 10^-9 이하이어야 하기 때문이다.

 

float과 double의 차이점은 정밀도이다.  이때, 정밀도란, 유효자릿수가 뜻하는 것이다. 즉, 몇자리까지 오차없이 표현할 수 있는가이다.

float은 7자리, double은 15~16자리 까지 표현할 수 있다.

728x90

'💻코딩 > 💡Baekjoon' 카테고리의 다른 글

[백준] 1010 다리 놓기  (0) 2023.01.11
[백준] 1009 분산처리  (0) 2023.01.10
[백준] 1007 벡터 매칭  (1) 2023.01.07
[백준] 1005 ACM Craft  (0) 2023.01.06
[백준] 1004 어린 왕자  (1) 2022.12.27
728x90

import java.util.*;

public class Main{
    static Integer[][] dp = new Integer[41][2];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        dp[0][0] = 1;
        dp[0][1] = 0;
        dp[1][0] = 0;
        dp[1][1] = 1;

        int T = sc.nextInt();

        for(int i=0; i<T; i++) {
            int n = sc.nextInt();
            
            fibonacci(n);
            System.out.println(dp[n][0] + " " + dp[n][1]);
        }        
    }

    public static Integer[] fibonacci(int n) {
        if (dp[n][0] == null || dp[n][1] == null) {
            dp[n][0] = fibonacci(n-1)[0] + fibonacci(n-2)[0];
            dp[n][1] = fibonacci(n-1)[1] + fibonacci(n-2)[1];
        }

        return dp[n];
    }
}

🔝 동적계획법(Dynamic Programming)을 이용한 풀이이다.

 

이 문제는 이해하는 것도 짜는 것도 쉬웠다. 하지만 왜 난이도를 중으로 줬냐하면, 내가 풀은 내용은 틀렸고 이를 해결하기 위해 많은 과정을 거쳤기때문이다😂😂

 

일단, 처음에 나는 일반 피보나치 수열을 사용하는 방법에서 0과 1의 호출 수를 count만 하도록 코드를 짰다. 즉, 재귀 호출을 이용한 것이다.

 

하지만 컴파일 후, 테스트케이스의 값과 n 값을 주어줬을 때 답을 내는 과정에서 오류가 났고 이를 해결하기 위해서는 동적 계획법을 사용해야 한다는 걸 알았다‼

 

이때 동적 계획법이란 아래와 같다.

어떤 주어진 문제를 작은 문제로 쪼개서 풀어나감에 있어 반복되는 호출을 줄이는 방법.

피보나치를 사용할 때, 재귀 호출을 통해 반복되는 호출을 줄인 것은 틀리지 않았으나, 0과 1을 호출하는 수를 세는 방법에서 틀렸다.

 

dp라는 Integer 타입의 이차원 배열을 생성하고, size를 지정해주었다. 이때, 이차원 배열을 통해 n=0일 때, 0과 1의 호출 수, n=1일 때, 0과 1의 호출 수를 dp 배열에 저장하여 재귀 호출을 하는 것이다💡

 

또한, 이때 int[][] 배열을 사용할 시 모든 배열의 값을 -1과 같은 값으로 모두 초기화를 해야 한다고 한다. 왜냐하면, 배열의 값이 null일 때, 즉, n의 값이 0 또는 1이 아닐 때를 체크하기 위해 초기화 값이 필요하다. 하지만 Integer 타입을 사용하면 모든 배열의 값을 -1과 같은 값으로 초기화를 꼭 하지 않아도 된다🙂

 

그 외에 코드를 작성하는 것은 재귀 호출을 이용하는 것과 같다. 다만, n의 값이 0 또는 1이 아닐 때 재귀 호출을 하는 것이다.

 

마지막으로 dp 배열에 저장되어 있는 0과 1을 호출한 수를 결과로 출력하면 되면 끝이다👍

728x90

'💻코딩 > 💡Baekjoon' 카테고리의 다른 글

[백준] 1005 ACM Craft  (0) 2023.01.06
[백준] 1004 어린 왕자  (1) 2022.12.27
[백준] 1002 터렛  (0) 2022.12.27
[백준] 1001 A-B  (1) 2022.12.27
[백준] 1000 A+B  (0) 2022.12.27

+ Recent posts