Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Day_Algorithm.iml
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Python" name="Python">
<configuration sdkName="Python 3.13 (untitled)" />
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Python 3.13 (untitled) interpreter library" level="application" />
</component>
</module>
54 changes: 54 additions & 0 deletions src/백준/Gold/A와B2/A와B2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import sys
input=sys.stdin.readline
S=input().strip()
T=input().strip()

def dfs(T):
if len(T)==len(S):
if T==S:
print(1)
exit()
elif T!=S:
return
if T[-1]=="A":
new_a=T[:-1]
dfs(new_a)
if T[0]=="B":
new_b=T[1:]
new_b=new_b[::-1]
dfs(new_b)

dfs(T)
print(0)

# import sys
# input = sys.stdin.readline
#
# S = input().strip()
# T = input().strip()
#
# def dfs(t):
# # 1. 종료 조건: 길이가 같아졌을 때
# if len(t) == len(S):
# return t == S # 같으면 True, 다르면 False 반환
#
# # 2. 가지치기 & 재귀 호출
#
# # Case A: 맨 뒤가 'A'라면 -> 떼고 재귀
# if t[-1] == 'A':
# if dfs(t[:-1]): # A를 뗀 문자열을 넘김
# return True
#
# # Case B: 맨 앞이 'B'라면 -> 떼고 뒤집어서 재귀
# if t[0] == 'B':
# # t[1:] (B 떼기) -> [::-1] (뒤집기)
# if dfs(t[1:][::-1]):
# return True
#
# return False # 둘 다 안 되면 False
#
# # 실행
# if dfs(T):
# print(1)
# else:
# print(0)
93 changes: 93 additions & 0 deletions src/백준/Gold/A와B2/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
역방향 풀이의 3가지 핵심 신호
1. 자유도
정방향: 자유도가 높음
역방향: 맨 뒤가 A여야만 뗼 수 있음, 그리고 맨 앞이 B여야만 뒤집고 뗄 수 있음
2. 생성 VS 소멸
정방향: 만들어가는 과정 -> 생성의 영역
역방향: 축소하는 과정 -> 소멸의 과정 역추적
3. 도착하는 곳이 특정 문자열 패턴일때
숫자 5 -> 100을 만드는 과정은 정해져 있지 않아 오히려 BFS와 같은 최단거리가 적합
문자열 S->T 구체적인 한가지 방식으로 문자열이 만들어짐

### Return 과 exit() 의 차이
### 문자열 슬라이싱 하는 방법
### 재귀 함수에서 매개변수 T를 진짜로 자르면 깊이 탐색했다가 돌아와서 예를 들어 dfs(3)의 길이가 3부터 시작해야 되는데 T를 진짜로 건들면 줄어든 T로 탐색하기 때문에 오류남


---

# [Gold V] A와 B 2 - 12919

[문제 링크](https://www.acmicpc.net/problem/12919)

### 성능 요약

메모리: 512 MB, 시간: 2 초

### 분류

문자열, 브루트포스 알고리즘, 재귀, 백트래킹

### 문제 설명

수빈이는 A와 B로만 이루어진 영어 단어가 존재한다는 사실에 놀라움을 금치 못하고 있다. 수빈이는 지금까지 많은 단어를 만들었는데, 그것을 모두 외우기는 너무 어렵기 때문에, 단어를 만들 때 감으로 만들려고 한다. 수빈이는 알파벳 A와 B로만 이루어진 단어 S를 주어졌을 때, 이 단어를 알파벳 A와 B로만 이루어진 단어 T로 바꿀 수 있는지 궁금해졌다.

S를 T로 바꾸는 게임은 다음과 같은 두 가지 연산만 가능하다.

1. 문자열의 뒤에 A를 추가한다.
2. 문자열의 뒤에 B를 추가하고 문자열을 뒤집는다.

주어진 조건을 이용해서 S를 T로 만들 수 있는지 없는지 알아내는 프로그램을 작성하시오.

### 입력

첫째 줄에 S가 둘째 줄에 T가 주어진다. (1 ≤ S의 길이 ≤ 49, 2 ≤ T의 길이 ≤ 50, S의 길이 < T의 길이)

### 출력

S를 T로 바꿀 수 있으면 1을, 없으면 0을 출력한다.

### 예제 입력 1

```text
A
BABA

```

### 예제 출력 1

```text
1

```

### 예제 입력 2

```text
BAAAAABAA
BAABAAAAAB

```

### 예제 출력 2

```text
1

```

### 예제 입력 3

```text
A
ABBA

```

### 예제 출력 3

```text
0

```
7 changes: 7 additions & 0 deletions src/백준/Gold/N_Queen/howtosolve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1. 순차적인 결정: 1번 줄 결정 -> 2번 줄 결정 -> ---(트리 구조)
2. 지금 이 결정이 괜찮은지 바로 체크
3. 안될 놈이면 뒤의 잘못된 경우의 수를 가지치기 해버리면 탐색 시간이 확 줄어듬

경우의 수가 너무 많아서 다 해볼 순 없는데, 순서대로 진행하면서 중간에 틀린걸 감지할 수 있으니, 가다가 아니면 되돌아오는 방식을 풀기
n이 작음 보통 백트래킹 문제는 10-15사이
선택의 연속: a를 고르고 그다음 b를 고르고 앞의 선택이 뒤의 선택에 영향을 줄 때
27 changes: 27 additions & 0 deletions src/백준/Gold/N_Queen/n-queen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import sys

n=int(sys.stdin.readline())

map=[0]*n
answer=0

# 가지치기
def check(row_index):
for i in range(row_index):
if map[row_index]==map[i] or abs(map[row_index]-map[i])==abs(row_index-i):
return False
return True

def dfs(row_index):
global answer
if row_index==n:
answer+=1
return

for col_index in range(n):
map[row_index]=col_index
if check(row_index):
dfs(row_index+1)

dfs(0)
print(answer)
94 changes: 94 additions & 0 deletions src/백준/Gold/가장가까운_공통조상/MY.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// 배열 문제를 풀면서 항상 헷갈리고 거부감이 들었던 부분은
// 배열의 크기를 어떤식으로 할당하는건지의 문제 어떨떄는 n+1, 어떨때는 n-1 boolean[] 배열의 크기 이런건 어떤식으로 정해지는건지
배열 크기 선언에 대해서 헷갈리는 부분이 있어서 정리해보고자 한다
배열 선언을 할 때 배열의 크기 N만큼 만들어줄 때와 그렇지 않고 N+1만큼의 크기를 만들어줄때를 비교해보자면
new int[n] 은 0부터 n-1까지 인덱스를 쓰는 경우에 0인덱스를 살려서 사용하는 문제의 경우 그대로 n만큼의 크기를
만약 문제에서 1번 노드, 3번 사람, 5번 도시와 같이 숫자가 1부터 주어질 경우에는 0부터 n까지의 크기 new int[n+1]을
사용해 0은 무시하고 1부터 인덱스를 사용하여 편의성을 더한다 만약 크기가 n이고 16번 노드는
parent[b-1] = a-1 과 같이 복잡하게 계산해주어야 하지만 만약 n+1이라면
parent[b] = a 와 같이 16번 노드는 16번 인덱스에 저장하면 되고 실수를 방지할 수 있게 된다

parent[B] = A; (3584번 LCA 문제)
만약 int[n]으로 만들었다면, 16번 노드는 15번 인덱스에 저장해야 합니다.

parent[B-1] = A-1; // 코드가 지저분해지고 헷갈림
int[n+1]로 만들면, 16번 노드는 그냥 16번 인덱스에 저장하면 됩니다.
parent[B] = A; // 코드가 직관적이고 실수가 줄어듦

결론: 문제의 '번호'와 배열의 '인덱스'를 일치시키기 위해 n+1을 사용합니다.

`while` 루프의 조건을 정하는 건 처음엔 정말 헷갈리죠.

`!=`를 써야 할지 `==`를 써야 할지 헷갈릴 때 쓰는 **가장 확실한 꿀팁**은, `while`의 조건을 "언제 멈추는가?"가 아니라 \*\*"이 루프가 계속 돌아가야 하는 이유(조건)"\*\*로 생각하는 것입니다.

`while`은 괄호 안의 조건이 `true`인 \*\*"동안"\*\*에만 계속 돕니다.

-----

## \#\# 1. `!=` (Not Equal) / `>` / `<` 를 쓸 때

**"\~가 될 때까지"** 라는 **목표 지향적** 루프에 씁니다.

변수가 계속 변하면서 **특정 "목표 값"에 도달하면 멈춰야 할 때** 사용합니다.

* **멈추는 조건:** `n == 0`

* **계속 도는 조건:** "n이 0이 아닌 **동안**" → `while (n != 0)` (혹은 `while (n > 0)`)

* **멈추는 조건:** `stack.isEmpty() == true` (스택이 비면 멈춤)

* **계속 도는 조건:** "스택이 비어있지 않은 **동안**" → `while (!stack.isEmpty())`

* **멈추는 조건:** `answer == input` (정답을 맞히면 멈춤)

* **계속 도는 조건:** "정답과 입력이 다른 **동안**" → `while (answer != input)`

-----

## \#\# 2. `==` (Equal) / `boolean` 변수를 쓸 때

**"\~인 동안"** 이라는 **상태 유지** 루프에 씁니다.

특정 변수가 `true`이거나 특정 상태일 때만 계속 돌아야 할 때 사용합니다.

* **계속 도는 조건:** "`isRun`이라는 '깃발'이 `true`인 **동안**"

* **코드:** `while (isRun == true)` (또는 간단히 `while (isRun)`)

* *(루프 안에서 `if (...) { isRun = false; }` 코드로 멈춤)*

* **계속 도는 조건:** "`count`가 10보다 작은 **동안**"

* **코드:** `while (count < 10)`

-----

## \#\# 🚨 가장 치명적인 실수: `=` vs `==`

초보자가 가장 많이 하는 실수입니다.

* **`=` (할당 연산자):** 값을 **"넣어라"** (덮어쓰기)
* **`==` (비교 연산자):** 값이 **"같은지 물어봐라"** (True/False)

#### **❌ 잘못된 코드 (거의 99% 무한루프)**

```java
int x = 0;
while (x = 5) { // 🛑 실수! x에 5를 "넣어라"
// x는 5가 되고, while(5)는 true로 취급되어 무한히 돕니다.
}
```

#### **✅ 올바른 코드**

```java
int x = 0;
while (x == 5) { // "x가 5와 같은가?" (지금은 false라 안 돔)
// ...
}

while (x != 5) { // "x가 5와 다른가?" (true라 돔)
// ...
x++;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package 백준.Gold.가장가까운_공통조상;

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

public class 가까운_공통조상 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine()); //테스트 케이스 수

// t가 2이면 2번 실행 t-- 이기 때문에 2 그리고 1 실행되고 0일때는 실행 x
while (t-->0) {
// 정점 n을 받기
int n = Integer.parseInt(br.readLine());
// 부모 배열 선언
int[] parent = new int[n + 1];
// 부모 자식 관계 맺어주기
for(int i=0;i<n-1;i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken()); //부모
int b = Integer.parseInt(st.nextToken()); //자식
// 부모 자식 연결
parent[b] = a; // b의 부모는 a이다
}

// 조상을 구할 노드 2개
StringTokenizer st = new StringTokenizer(br.readLine());
int node1 = Integer.parseInt(st.nextToken());
int node2 = Integer.parseInt(st.nextToken());

// 가까운 조상 찾아주기
// 조상을 타고 올라가면서 방문 체크 해줄 배열 선언
boolean[] visited = new boolean[n + 1];
// 조상을 타고 올라갈걸 어떻게 구현할거야 강아
// 올라가야 하니까 부모 정보를 저장할 parent 배열이 필요하겠구나
int currentNode = node1;
while (currentNode != 0) {
visited[currentNode] = true;
currentNode=parent[currentNode];
}

currentNode = node2;
// 현재 노드가 parent[c urrentNode]가 0이 아니다
while(currentNode!=0){
if(visited[currentNode]){
System.out.println(currentNode);
break;
}
currentNode = parent[currentNode];
}
}
}
}
Loading