Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[최단경로] 2171024 신수정 #362

Open
wants to merge 32 commits into
base: 2171024-신수정2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
de9881a
[4월 12일] 동적 계획법 강의 자료 업로드
jk0527 Apr 12, 2023
8ef72d6
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 Apr 12, 2023
6223f7e
[4월 12일] 동적 계획법 리드미 업로드
jk0527 Apr 12, 2023
da38b52
[4월 14일] 동적 계획법 강의 자료 수정
jk0527 Apr 14, 2023
53b5bfa
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 Apr 14, 2023
3a83c8a
[4월 14일] 리드미 수정
jk0527 Apr 14, 2023
149f4c0
[4월 14일] 동적 계획법 라이브코딩 코드 업로드
jk0527 Apr 14, 2023
1d0e018
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 Apr 14, 2023
1bcacb0
[4월 14일] 동적 계획법 리드미 수정
jk0527 Apr 14, 2023
cbdb583
[5월 2일] 동적 계획법 강의자료 수정
jk0527 May 1, 2023
c2091d7
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 May 1, 2023
1b3b114
[5월 2일] 백트래킹 과제 코드 업로드
jk0527 May 1, 2023
86da014
[5월 2일] 동적 계획법 과제 코드 업로드
jk0527 May 1, 2023
bd2b014
[5월 2일] 백트래킹 리드미 수정
jk0527 May 1, 2023
d51f618
[5월 2일] 동적 계획법 리드미 수정
jk0527 May 1, 2023
93c419c
[5월 5일] 이분 탐색 리드미 업로드
jk0527 May 5, 2023
88830b6
[5월 5일] 이분 탐색 강의 자료 업로드
jk0527 May 5, 2023
5a6372c
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 May 5, 2023
ad6eebb
[5월 5일] 이분 탐색 라이브 코딩 코드 업로드
jk0527 May 5, 2023
9f9b791
[5월 5일] 이분 탐색 리드미 수정
jk0527 May 5, 2023
3a55ea1
[5월 5일] 리드미 수정
jk0527 May 5, 2023
cedeb06
[5월 9일] 이분 탐색 과제 코드 업로드
jk0527 May 9, 2023
7699152
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 May 9, 2023
bbfbc93
[5월 9일] 투 포인터 리드미 업로드
jk0527 May 9, 2023
7baa1de
[5월 10일] 이분 탐색 리드미 수정
jk0527 May 10, 2023
b6f7843
[5월 10일] 투 포인터 강의 자료 업로드
jk0527 May 10, 2023
b92e936
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 May 10, 2023
56d70ae
[5월 10일] 리드미 수정
jk0527 May 10, 2023
3549143
[0523] 트리 -필수문제
chock-cho May 23, 2023
0a250a4
[0523] 트리-필수문
chock-cho May 23, 2023
de869b8
[0530] 최단경로
chock-cho May 30, 2023
fe3f732
[0530] 최단경로
chock-cho May 30, 2023
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
10 changes: 5 additions & 5 deletions 08_백트래킹/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@

| 문제 번호 | 문제 이름 | 난이도 | 풀이 링크 | 분류 |
| :-----------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------: | :-------: | :--------------: |
| <a href="https://www.acmicpc.net/problem/20055" target="_blank">20055</a> | <a href="https://www.acmicpc.net/problem/20055" target="_blank">컨베이어 벨트 위의 로봇</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/11.svg"/> | [C++]() | 구현, 시뮬레이션 |
| <a href="https://www.acmicpc.net/problem/14888" target="_blank">14888</a> | <a href="https://www.acmicpc.net/problem/14888" target="_blank">연산자 끼워넣기</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/10.svg"/> | [C++]() | 백트래킹 |
| <a href="https://www.acmicpc.net/problem/14889" target="_blank">14889</a> | <a href="https://www.acmicpc.net/problem/14889" target="_blank">스타트와 링크</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/9.svg"/> | [C++]() | 백트래킹 |
| <a href="https://www.acmicpc.net/problem/20055" target="_blank">20055</a> | <a href="https://www.acmicpc.net/problem/20055" target="_blank">컨베이어 벨트 위의 로봇</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/11.svg"/> | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/08_%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9/%ED%95%84%EC%88%98/20055.cpp) | 구현, 시뮬레이션 |
| <a href="https://www.acmicpc.net/problem/14888" target="_blank">14888</a> | <a href="https://www.acmicpc.net/problem/14888" target="_blank">연산자 끼워넣기</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/10.svg"/> | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/08_%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9/%ED%95%84%EC%88%98/14888.cpp) | 백트래킹 |
| <a href="https://www.acmicpc.net/problem/14889" target="_blank">14889</a> | <a href="https://www.acmicpc.net/problem/14889" target="_blank">스타트와 링크</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/9.svg"/> | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/08_%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9/%ED%95%84%EC%88%98/14889.cpp) | 백트래킹 |

### 도전

| 문제 번호 | 문제 이름 | 난이도 | 풀이 링크 | 분류 |
| :--------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------: | :-------: | :------: |
| <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42839" target="_blank">프로그래머스</a> | <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42839" target="_blank">소수 찾기</a> | **Lv.2** | [C++]() | 백트래킹 |
| <a href="https://www.acmicpc.net/problem/2580" target="_blank">2580</a> | <a href="https://www.acmicpc.net/problem/2580" target="_blank">스도쿠</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/12.svg"/> | [C++]() | 백트래킹 |
| <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42839" target="_blank">프로그래머스</a> | <a href="https://school.programmers.co.kr/learn/courses/30/lessons/42839" target="_blank">소수 찾기</a> | **Lv.2** | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/08_%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9/%EB%8F%84%EC%A0%84/%EC%86%8C%EC%88%98_%EC%B0%BE%EA%B8%B0.cpp) | 백트래킹 |
| <a href="https://www.acmicpc.net/problem/2580" target="_blank">2580</a> | <a href="https://www.acmicpc.net/problem/2580" target="_blank">스도쿠</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/12.svg"/> | [C++_v1](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/08_%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9/%EB%8F%84%EC%A0%84/2580_v1.cpp) </br> [C++_v2](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/08_%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9/%EB%8F%84%EC%A0%84/2580_v2.cpp) | 백트래킹 |

---

Expand Down
119 changes: 119 additions & 0 deletions 08_백트래킹/도전/2580_v1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include <iostream>
#include <vector>

using namespace std;

const int MAX = 9;

bool is_finished;
int sudoku[MAX][MAX];

bool checkRow(int r, int n) {
for (int i = 0; i < MAX; i++) {
if (sudoku[r][i] == n) {
return false;
}
}

return true;
}

bool checkCol(int c, int n) {
for (int i = 0; i < MAX; i++) {
if (sudoku[i][c] == n) {
return false;
}
}

return true;
}

bool checkSquare(int r, int c, int n) {
// (base_r, base_c): (r,c)가 속한 정사각형의 왼쪽 상단 꼭짓점 좌표
int base_r = r / 3 * 3;
int base_c = c / 3 * 3;

for (int i = 0; i < (MAX / 3); i++) {
for (int j = 0; j < (MAX / 3); j++) {
if (sudoku[base_r + i][base_c + j] == n) {
return false;
}
}
}

return true;
}

bool check(int r, int c, int n) {
return checkRow(r, n) && checkCol(c, n) && checkSquare(r, c, n);
}

/**
* (0, 0)부터 차례로 빈칸을 채워나간다
*
* idx: 왼쪽 상단부터 매긴 칸 번호, (row * 9) + col
*/
void fillSudoku(int idx) {
// 재귀 호출 종료 조건: 스도쿠 판을 다 채운 경우
if (idx == MAX * MAX) {
is_finished = true;
return;
}

int r = idx / MAX;
int c = idx % MAX;

// 빈칸이 아닌 경우
if (sudoku[r][c] != 0) {
// 바로 다음 칸 탐색
fillSudoku(idx + 1);
}
// 빈칸인 경우
else {
// i: 이번 빈칸에 넣을 수
for (int i = 1; i <= MAX; i++) {
// 불가능한 경우
if (!check(r, c, i)) {
continue;
}

sudoku[r][c] = i;
fillSudoku(idx + 1);
if (is_finished) { // 채우기에 성공했으면
return; // 현재 상태를 출력해야 하므로 원상태로 돌려놓지 않고 즉시 종료
}
sudoku[r][c] = 0;
}
}
}

/**
* 모든 빈칸에 1~9를 넣어본다.
* 단, 가로, 세로, 정사각형에 같은 수가 있는 경우는 가지치기해준다.
* 가지치기를 위해 가로 9칸, 세로 9칸, 정사각형 9칸을 모두 탐색한다.
*
* 가지치기 시간 복잡도: O(N)
* 약 245ms
*/
int main()
{
// 입력
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
cin >> sudoku[i][j];
}
}

// 연산
fillSudoku(0);

// 출력
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
cout << sudoku[i][j] << " ";
}
cout << "\n";
}

return 0;
}
112 changes: 112 additions & 0 deletions 08_백트래킹/도전/2580_v2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include <iostream>
#include <vector>

using namespace std;

const int MAX = 9;

bool is_finished;
int sudoku[MAX][MAX];
bool is_in_row[MAX][MAX + 1]; // is_in_row[r][n]: r번 행에 n이 존재하는지 여부
bool is_in_col[MAX][MAX + 1]; // is_in_col[c][n]: c번 열에 n이 존재하는지 여부
bool is_in_square[MAX][MAX + 1]; // is_in_square[s][n]: s번 정사각형에 n이 존재하는지 여부

/**
* 정사각형 계산 함수
* (r, c)가 속한 3*3 정사각형의 번호를 리턴
*/
int calcSquare(int r, int c) {
return (r / 3) * 3 + (c / 3);
}

void fill(int r, int c, int n) {
sudoku[r][c] = n;
is_in_row[r][n] = true;
is_in_col[c][n] = true;
is_in_square[calcSquare(r, c)][n] = true;
}

void empty(int r, int c) {
int n = sudoku[r][c];
sudoku[r][c] = 0;
is_in_row[r][n] = false;
is_in_col[c][n] = false;
is_in_square[calcSquare(r, c)][n] = false;
}

bool check(int r, int c, int n) {
return !is_in_row[r][n] && !is_in_col[c][n] && !is_in_square[calcSquare(r, c)][n];
}

/**
* (0, 0)부터 차례로 빈칸을 채워나간다
*
* idx: 왼쪽 상단부터 매긴 칸 번호, (row * 9) + col
*/
void fillSudoku(int idx) {
// 재귀 호출 종료 조건: 스도쿠 판을 다 채운 경우
if (idx == MAX * MAX) {
is_finished = true;
return;
}

int r = idx / MAX;
int c = idx % MAX;

// 빈칸이 아닌 경우
if (sudoku[r][c] != 0) {
// 바로 다음 칸 탐색
fillSudoku(idx + 1);
}
// 빈칸인 경우
else {
// i: 이번 빈칸에 넣을 수
for (int i = 1; i <= MAX; i++) {
// 불가능한 경우
if (!check(r, c, i)) {
continue;
}

fill(r, c, i);
fillSudoku(idx + 1);
if (is_finished) { // 채우기에 성공했으면
return; // 현재 상태를 출력해야 하므로 원상태로 돌려놓지 않고 즉시 종료
}
empty(r, c);
}
}
}

/**
* 모든 빈칸에 1~9를 넣어본다.
* 단, 가로, 세로, 정사각형에 같은 수가 있는 경우는 가지치기해준다.
* 가지치기를 위해 각 가로, 세로, 정사각형에 특정 숫자가 존재하는지 여부를 배열로 관리한다.
*
* 가지치기 시간 복잡도: O(1)
* 약 90ms
*/
int main()
{
int n;

// 입력
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
cin >> n;
fill(i, j, n);
}
}

// 연산
fillSudoku(0);

// 출력
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
cout << sudoku[i][j] << " ";
}
cout << "\n";
}

return 0;
}
80 changes: 80 additions & 0 deletions 08_백트래킹/도전/소수_찾기.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

const int MAX_VAL = 1e8;
const int MAX_N = 7;

int n;
int answer = 0;
int nums[MAX_N];
bool is_used[MAX_N]; // is_used[i]: i번 조각을 현재 사용중인지 여부
bool is_counted[MAX_VAL]; // is_counted[i]: i를 카운트 한 적이 있는지 여부

bool isPrime(int x) {
if (x == 0 || x == 1) {
return false;
}

for (long long i = 2; i * i <= x; i++) {
if (x % i == 0) {
return false;
}
}

return true;
}

/**
* 총 N개가 될 때까지 종이 조각을 하나씩 뽑아서 이어붙인다.
* N개를 뽑는 중간 과정에서 만들어지는 수(1 ~ (N-1)개의 조각으로 만든)도 체크해주면서 지나가면,
* 종이 조각들로 만들 수 있는 모든 수를 고려하게 된다.
*
* cnt: 현재까지 뽑은 종이 조각 개수
* val: 현재까지 뽑은 종이 조각으로 만든 수
*/
void backtrack(int cnt, int val) {
// 현재까지 만든 수가 소수인지 체크
// cnt == 0인 경우는 아직 아무것도 뽑지 않았으므로 내가 만든 수가 아님에 유의
if (cnt > 0 && !is_counted[val] && isPrime(val)) {
answer++;
is_counted[val] = true;
}

// 재귀 호출 종료 조건: N개를 모두 뽑은 경우
if (cnt == n) {
return;
}

// i: 다음으로 뽑을 수
for (int i = 0; i < n; i++) {
if (is_used[i]) {
continue;
}

is_used[i] = true;
backtrack(cnt + 1, val * 10 + nums[i]);
is_used[i] = false;
}
}

int solution(string numbers) {
// 입력 처리
n = numbers.size();
for (int i = 0; i < n; i++) {
nums[i] = numbers[i] - '0';
}

// 연산
backtrack(0, 0);

return answer;
}

int main() {
cout << solution("17");

return 0;
}
Empty file.
Loading