1, 2, 3 더하기
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int N, cnt;
public static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int T = Integer.parseInt(st.nextToken());
for(int testcase = 1; testcase <= T; testcase++){
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
cnt = 0;
dfs(0);
sb.append(cnt).append("\n");
}
System.out.println(sb);
}
public static void dfs(int sum){
if(sum == N){
cnt++;
return;
}
for(int i = 1; i <= 3; i++){
if(sum + i > N) break;
dfs(sum + i);
}
}
}
암호만들기
L, C 가 헷갈려서 시간 끔 확실히 생각필요
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static int L, C;
public static char[] code;
public static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// 1. 입력변수 받아오기
L = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
code = new char[C];
st = new StringTokenizer(br.readLine());
for(int i = 0; i < C; i++){
code[i] = st.nextToken().charAt(0);
}
Arrays.sort(code);
// 2. 조합 재귀
dfs(0, 0, "");
// 4. 정답 출력
System.out.println(sb);
}
public static void dfs(int at, int depth, String ans){
// 3-1. depth에 닿고
if(depth == L){
// 모음이 1개 자음이 2개일경우 출력
int gather = 0;
int consonant = 0;
for(int i = 0; i < L; i++){
char a = ans.charAt(i);
if(a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u'){
gather += 1;
} else {
consonant += 1;
}
}
if (gather >= 1 && consonant >= 2) {
sb.append(ans).append("\n");
}
return;
}
// 3-2. 모든 알파벳 순회
for(int i = at; i < C; i++){
dfs(i + 1, depth + 1, ans + code[i] );
}
}
}
퇴사
이전에 풀었던 방법
import java.util.*;
public class Main {
static int n, max = 0;
static int[][] a;
static int arr = 0;
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
a = new int[2][n];
for (int i = 0; i < n; i++) {
a[0][i] = sc.nextInt();
a[1][i] = sc.nextInt();
}
dfs(0,0);
sb.append(max);
System.out.println(sb);
}
static void dfs(int at, int cost) {
if(at <= n) {
if(cost>max) {
max = cost;
}
} else {
return;
}
for(int i = at;i < n;i ++) {
dfs(i + a[0][i], cost + a[1][i]);
}
}
}
이번에 푼방법
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static int N;
public static int[][] arr;
public static int max = Integer.MIN_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// 1. 입력변수 받아오기
N = Integer.parseInt(st.nextToken());
arr = new int[N][2];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
arr[i][0] = Integer.parseInt(st.nextToken());
arr[i][1] = Integer.parseInt(st.nextToken());
}
// 2. 조합 재귀
dfs(0, 0);
// 4. 정답 출력
System.out.println(max);
}
public static void dfs(int depth, int prise){
if(depth == N){
max = Math.max(max, prise);
return;
}
if(depth > N){
return;
}
dfs(depth+arr[depth][0], prise+arr[depth][1]);
dfs(depth+1, prise);
}
}
dp 로 푸는 법
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int N;
public static int[][] arr;
public static int[] dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// 1. 입력변수 받아오기
N = Integer.parseInt(st.nextToken());
arr = new int[N][2];
dp = new int[N + 1];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
arr[i][0] = Integer.parseInt(st.nextToken());
arr[i][1] = Integer.parseInt(st.nextToken());
}
for(int i = N - 1; i >= 0; i--){
int take = 0;
if(i + arr[i][0] <= N) take = arr[i][1] + dp[i + arr[i][0]];
int skip = dp[i + 1];
dp[i] = Math.max(take, skip);
}
// 4. 정답 출력
System.out.println(dp[0]);
}
}
스타트와 링크
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int N, min = Integer.MAX_VALUE;
public static int[] arr, start, link;
public static int[][] ability;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
ability = new int[N][N];
arr = new int[N];
start = new int[N/2];
link = new int[N/2];
for(int i = 0; i < N; i++){
st = new StringTokenizer(br.readLine());
for(int j = 0; j < N; j++){
ability[i][j] = Integer.parseInt(st.nextToken());
}
}
// 1. 팀정하기
dfs(0,0);
// 2. 능력치 계산
// 팀을 반반으로 나눠야 된다
// 3. 정답출력
System.out.println(min);
}
public static void dfs(int at, int depth){
if(depth == N / 2){
int cnt1 = 0, cnt2 = 0;
// for(int i = 0; i < N; i++){
// System.out.print(i + ": " + arr[i] + " ");
// }
for(int i = 0; i < N; i++){
if(arr[i] == 1){
start[cnt1++] = i;
}else {
link[cnt2++] = i;
}
}
int startS = sum(start);
int linkS = sum(link);
min = Math.min(min, Math.abs(startS - linkS));
return;
}
for(int i = at; i < N; i++){
arr[i] = 1;
dfs(i + 1, depth + 1);
arr[i] = 0;
}
}
public static int sum(int[] arr){
int sum = 0;
for(int i = 0; i < arr.length; i++){
for(int j = i + 1; j < arr.length; j++){
sum = sum + ability[arr[i]][arr[j]] + ability[arr[j]][arr[i]];
}
}
return sum;
}
}
링크와 스타트
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
public static int N, min = Integer.MAX_VALUE, startN = 0, linkN = 0;
public static int[] arr;
public static List<Integer> start, link;
public static int[][] ability;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
ability = new int[N][N];
arr = new int[N];
for(int i = 0; i < N; i++){
st = new StringTokenizer(br.readLine());
for(int j = 0; j < N; j++){
ability[i][j] = Integer.parseInt(st.nextToken());
}
}
// 1. 팀정하기 (팀 인원수 1 ~ N)
for(int i = 1; i <= N / 2; i++){
dfs(0, 0, i);
}
// 3. 정답출력
System.out.println(min);
}
public static void dfs(int at, int depth, int member){
if(depth == member){
start = new ArrayList<>();
link = new ArrayList<>();
for(int i = 0; i < N; i++){
if(arr[i] == 1) start.add(i);
else link.add(i);
}
startN = calculate(start);
linkN = calculate(link);
min = Math.min(min, Math.abs(startN - linkN));
return;
}
for(int i = at; i < N; i++){
arr[i] = 1;
dfs(i + 1, depth + 1, member);
arr[i] = 0;
}
}
public static int calculate(List<Integer> list){
int sum = 0;
for(int i = 0; i < list.size(); i++){
int first = list.get(i);
for(int j = i + 1; j < list.size(); j++){
int second = list.get(j);
sum = sum + ability[first][second] + ability[second][first];
}
}
return sum;
}
}
다 풀어놓고 해맷다.
1. 조합 짤때 dfs(i, depth + 1, member) => dfs(i + 1, depth + 1, member);
2. 계산할때 sum = sum + ability[first][second] + ability[first][second] => sum = sum + ability[first][second] + ability[second][first]
컴파일 에러가 안뜨는 대표적인 실수 지금 한걸 다행이라 생각해야할까? 아쉽긴하다. 오래걸리진 않았다. 풀이시간 약 30분
고민하는 시간이 오래걸린건 아닌데 생각보다 오래걸린거 같다. 타자치는 속도나 코드짜는 속도가 느려진거같다.
근데 사실 이 방법이 좀 아닌거 같은데 왜 짜보면 또 정답인건지 의문이다. 시간 계산 해봤을때는 더 오래걸릴꺼라 생각해서 시간초과의 압박의 느꼈었다.
순열은
3. 완전 검색 - 순열
- 순열 (Permutation)
- 서로 다른 것들 중 몇 개를 뽑아서 한 줄로 나열하는 것
- 서로 다른 n개 wnd r개를 택하는 순열은 아래와 같이 표현한다.nPn = n!
- nPr = n * (n-1) * (n-2) * … * (n-r+1)
- N개의 요소들에 대해서 n!개의 순열들이 존재한다.
- 12! = 479,001,600
- n > 12인 경우, 시간 복잡도 폭발적으로 상승
💡 10! 정도만 순열로 문제 풀이를 기대 해 볼 수 있다.
이번 문제는 조합이긴하지만 조합보다는 그냥 부분집합으로 보는게 좋은거같다. 부분집합은 O(2^n)정도라 20까지는 괜찮다. 딱
gpt 의 도움을 받아 이 문제를 어떻게 풀면 시간복잡도가 더 줄어들지 물어봤더니 세가지 정도를 추천해주었다.
1. 0번 선수를 무조건 링크팀에 넣고 시작하기
2. 팀의 점수를 재귀할때마다 필요한 값만 계산해주는 방식
3. 최소가 0이면 더 할필요 없이 바로 빠져나오기
맨 처음 GPT 가 짜준코드 넣으니까 안돌아가더니 피드백 한번 후 잘돌아감
시간초도 많이 줄어듬 와 신기하네
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
public static int N, min = Integer.MAX_VALUE;
public static int[] arr;
public static int[][] ability, P;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
ability = new int[N][N];
P = new int[N][N];
arr = new int[N];
arr[0] = 1;
for(int i = 0; i < N; i++){
st = new StringTokenizer(br.readLine());
for(int j = 0; j < N; j++){
ability[i][j] = Integer.parseInt(st.nextToken());
}
}
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
P[i][j] = ability[i][j] + ability[j][i];
}
}
// 1. 팀정하기 (팀 인원수 1 ~ N)
dfs(1, 1, 0, 0);
// 3. 정답출력
System.out.println(min);
}
public static void dfs(int idx, int cntA, int scoreA, int scoreB){
if (idx == N) {
// 팀 A와 팀 B는 둘 다 1명이상이어야 함
int cntB = N - cntA;
if (cntA >= 1 && cntB >= 1) {
int diff = Math.abs(scoreA - scoreB);
if (diff < min) {
min = diff;
// if (min == 0) {
// System.out.println(0);
// System.exit(0);
// }
}
}
return;
}
// 1) idx를 팀 A에 넣는 경우
int addA = 0;
// 이미 결정된 j<idx 중 팀 A에 있는 사람들과의 P만 더함 (증분 갱신)
for (int j = 0; j < idx; j++) {
if (arr[j] == 1) addA += P[idx][j];
}
arr[idx] = 1;
dfs(idx + 1, cntA + 1, scoreA + addA, scoreB);
arr[idx] = 0;
// 2) idx를 팀 B에 넣는 경우
int addB = 0;
for (int j = 0; j < idx; j++) {
if (arr[j] == 0) addB += P[idx][j];
}
// cntA 그대로
dfs(idx + 1, cntA, scoreA, scoreB + addB);
}
}
주석도 이해하기 쉽게 달아주고 변수명도 이해하기 훨씬 쉽다..
코테 공부를 하고 있는게 맞는건지 잘 모르겠다..ㅋㅋ 인터넷보니까 이거보다 잘 푼 버전은 없는거 같던데
근데 이상하게 내가 맨처음 1년전에 푼 버전도 좀 시간이 생각보단 빠르다
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Main {
public static int n, min = Integer.MAX_VALUE;
public static int[] arr, arr2, visited;
public static int[][] a;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// 1. 입력값 받아오기
n = Integer.valueOf(st.nextToken());
a = new int[n][n];
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
a[i][j] = Integer.valueOf(st.nextToken());
}
}
// 2. 팀을 나누기 위한 팀 배열 선언
// 2-1. 인원수를 다르게 팀원을 분배해서 팀 배열 만들기
for (int i = 1; i <= n / 2; i++) {
arr = new int[i];
arr2 = new int[n - i];
visited = new int[n];
dfs(0, 0, i);
}
System.out.println(min);
}
// 3. 팀 인원수에 따른 dfs 조합 만들기
public static void dfs(int at, int depth, int num) {
if (depth == num) {
int cnt = 0;
for(int i = 0;i<n;i++) {
if(visited[i] == 0) {
arr2[cnt] = i;
cnt++;
}
}
// 4-1. 1,2 번팀 능력치의 차이 구하기
int sum = Math.abs(power(arr, num) - power(arr2, n-num));
// 5. min과 비교했을때 더 작다면 min 초기화
if(min>sum) {
min = sum;
}
return;
}
for (int i = at; i < n; i++) {
arr[depth] = i;
visited[i] = 1;
dfs(i + 1, depth + 1, num);
visited[i] = 0;
}
}
// 팀의 능력치 합 구하는 함수
public static int power(int arr[], int num) {
int sum = 0;
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
sum += a[arr[i]][arr[j]];
}
}
return sum;
}
}
달라진 부분은 그닥없고 리스트에서 배열로 바꿨을 뿐인거같은데
부등호
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int k;
public static long min = Long.MAX_VALUE, max = Long.MIN_VALUE;
public static int[] sign, visited;
public static String minS = "", maxS = "";
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
// 1. 입력값 받아오기
k = Integer.parseInt(br.readLine());
sign = new int[k];
visited = new int[10];
st = new StringTokenizer(br.readLine());
for(int i = 0; i < k; i++){
char c = st.nextToken().charAt(0);
if(c == '>'){
sign[i] = 1;
}
}
for(int i = 0; i < 10; i++){
visited[i] = 1;
dfs(1, i + "");
visited[i] = 0;
}
System.out.println(maxS);
System.out.println(minS);
}
public static void dfs(int depth, String result){
if(depth == k + 1){
if(max < Long.parseLong(result)){
max = Long.parseLong(result);
maxS = result;
}
if(min > Long.parseLong(result)){
min = Long.parseLong(result);
minS = result;
}
return;
}
for(int i = 0; i < 10; i++){
if(visited[i] == 1) continue;
if(sign[depth - 1] == 1 && result.charAt(depth - 1) - '0' > i){
visited[i] = 1;
dfs(depth + 1, result + i);
visited[i] = 0;
} else if(sign[depth - 1] == 0 && result.charAt(depth - 1) - '0' < i) {
visited[i] = 1;
dfs(depth + 1, result + i);
visited[i] = 0;
}
}
}
}
자릿수 조심 char , Integer 비교 조심
'코딩테스트 > JAVA' 카테고리의 다른 글
| [백준 JAVA] 회귀한 프로그래머의 BFS 다시풀기 (0) | 2025.09.11 |
|---|---|
| [백준 JAVA] 회귀한 프로그래머의 그래프 1 다시풀기 (0) | 2025.09.05 |
| [백준 JAVA] 회귀한 프로그래머의 순열 응용 문제 다시 풀기 (3) | 2025.08.04 |
| [백준 JAVA] 회귀한 프로그래머의 순열 문제 다시 풀기 (2) | 2025.07.31 |
| [백준 JAVA] 회귀한 프로그래머의 N과 M 다시풀기 (3) | 2025.07.30 |