From d344daca36eae6e05248afddf8abc01504185d7a Mon Sep 17 00:00:00 2001 From: rahaaaiii Date: Sun, 12 Nov 2023 16:25:58 +0900 Subject: [PATCH 1/3] Create 20055.cpp --- .../20055.cpp" | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 "09_\353\260\261\355\212\270\353\236\230\355\202\271/20055.cpp" diff --git "a/09_\353\260\261\355\212\270\353\236\230\355\202\271/20055.cpp" "b/09_\353\260\261\355\212\270\353\236\230\355\202\271/20055.cpp" new file mode 100644 index 0000000..4cfe306 --- /dev/null +++ "b/09_\353\260\261\355\212\270\353\236\230\355\202\271/20055.cpp" @@ -0,0 +1,109 @@ +#include +#include + +using namespace std; + +struct info { // 내구도와 로봇 존재 여부 + int power;//내구도 + bool is_on;//로봇존재여부 +}; + +// 벨트를 한 칸 회전 +void rotateBelt(deque &belt, int n) { + belt.push_front(belt.back());//맨 뒤의 값을 맨 앞으로 보내기 + belt.pop_back();//맨 뒤의 값 삭제하기 + belt[n - 1].is_on = false; // 로봇이 내리는 위치 +} + +// 로봇을 움직일 수 있으면 한 칸 이동 +void moveRobot(deque &belt, int n) { + for (int i = n - 2; i >= 0; i--) { + if (!belt[i].is_on) {//로봇이 없을 때 + continue; + } + + if (!belt[i + 1].is_on && (belt[i + 1].power >= 1)) {// 다음 칸에 로봇이 없으면서 다음 칸에 내구도가 남아있을 때 + belt[i].is_on = false;//현재 벨트에는 로봇 삭제하고 + belt[i + 1].is_on = true;//다음 벨트에 로봇이동 + belt[i + 1].power--;//내구도 1감소 + } + + belt[n - 1].is_on = false; // 로봇이 내리는 위치 + } +} + +// 올리는 칸에 로봇을 올릴 수 있으면 올림 +void putRobot(deque &belt) { + if (!belt[0].is_on && belt[0].power >= 1) { + // 올리는 칸에 로봇이 존재하지 않고, 내구도가 남아있으면 + belt[0].is_on = true; + belt[0].power--; + } +} + +// 벨트의 내구도 체크 +bool checkFinish(deque &belt, int n, int k) { + int count = 0;//내구도가 0인 벨트 체크 + + for (int i = 0; i < 2 * n; i++) { + if (belt[i].power == 0) {//내구도가 0이되면 count값 1증가 + count++; + } + } + + return count >= k;//내구도가 0인 칸이 k개 이상인지 확인 +} + +int solution(deque &belt, int n, int k) { + int step = 1;//현재 몇번째 단계인지 기록 + while (true) { + rotateBelt(belt, n);//회전 + moveRobot(belt, n);//이동 + putRobot(belt);//로봇 올리기 + + // 내구도 체크하기 + if (checkFinish(belt, n, k)) { + return step;//현재 단계 반환 + } + step++;//단계 1증가 + } +} + + +/** + * [컨베이어 벨트 위의 로봇 문제] + * 1. 벨트가 각 칸 위의 로봇과 함께 한 칸 회전 + * 2. 가장 먼저 벨트에 올라간 로봇부터, 벨트 회전 방향으로 한 칸 이동할 수 있다면 이동 + * (이동가능: 이동하려는 칸에 로봇이 없고, 그 칸의 내구도가 1 이상이어야 함) + * 3. 올리는 위치에 있는 칸의 내구도가 0이 아니면 올리는 위치에 로봇 올림 + * 4. 내구도가 0인 칸의 개수가 k개 이상이라면 과정 종료. 그렇지 않다면 1로 돌아감 + * -> 1 ~ 3까지가 1단계 + * + * [문제 풀이] + * 회전과 관련이 깊은 자료구조 deque를 사용하여 풀이 + * + * 1번 벨트 회전: 벨트의 마지막 원소를 벨트 처음에 넣기 + * 2번 로봇 이동: 가장 먼저 올라간 로봇부터 고려해야 하므로 (내리는 위치 - 1)부터 (올리는 위치)까지 검사 + * -> 로봇 옮기는거 가능하면 존재여부 체크하고 내구도 감소 + * 3번 로봇 추가: 올리는 위치 칸 내구도 0이 아니라면 해당 칸 로봇 존재 여부 체크 + 내구도 감소 + * + * + * >> 주의: 칸 번호를 1번이 아닌 0번부터 시작하는 것으로 관리하고 있기 때문에, n번 칸이 아니라 n-1번 칸이 내리는 위치 << + */ + +int main() { + // 입력 + int n, k; + cin >> n >> k;//n과 k입력받기 + deque belt(2 * n); // 컨베이어 벨트의 내구도와 로봇 존재 여부 저장 + for (int i = 0; i < 2 * n; i++) {//2n만큼 반복 + cin >> belt[i].power;//벨트 내구 입력받기 + belt[i].is_on = false;//값 false로 처기화 + } + + // 연산 + int answer = solution(belt, n, k);//연산 함수 호출 + + // 출력 + cout << answer; +} \ No newline at end of file From 2cbce4cdeb1a17c117dbced84587a03f6b67eb69 Mon Sep 17 00:00:00 2001 From: rahaaaiii Date: Sun, 12 Nov 2023 16:41:18 +0900 Subject: [PATCH 2/3] Create 14888.cpp --- .../14888.cpp" | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 "09_\353\260\261\355\212\270\353\236\230\355\202\271/14888.cpp" diff --git "a/09_\353\260\261\355\212\270\353\236\230\355\202\271/14888.cpp" "b/09_\353\260\261\355\212\270\353\236\230\355\202\271/14888.cpp" new file mode 100644 index 0000000..610f14b --- /dev/null +++ "b/09_\353\260\261\355\212\270\353\236\230\355\202\271/14888.cpp" @@ -0,0 +1,86 @@ +// 14888번 연산자 끼워넣기: https://www.acmicpc.net/problem/14888 +#include +#include +#include + +using namespace std; + +const int INF = 1e9; +const int MAX_N = 11;//입력받을 수 있는 값을 최대 개수 +const int ADD = 0, SUB = 1, MUL = 2, DIV = 3;//각 숫자가 연산을 가르킴 +const int EXP_NUM = 4;//연산 경우는 4가지밖에 없으므로 4로 설정 + +int n; +int nums[MAX_N]; +int expression[EXP_NUM]; +int max_val = -INF, min_val = INF; + +/** + * 연산자를 하나씩, 총 (N-1)개가 될 때까지 뽑는다. + * + * cnt: 뽑은 연산자의 개수 + * curr_val: 현재 연산값 + */ +void backtrack(int cnt, int curr_val) { + // 재귀 호출 종료 조건: (N-1)개의 연산자를 다 뽑은 경우 + if (cnt == n - 1) {//뽑은 연산자 수가 입력받은 숫자-1이라면 + max_val = max(max_val, curr_val);//최대값 + min_val = min(min_val, curr_val);//최소값 + return; + } + + // i: 연산자 번호 + for (int i = 0; i < EXP_NUM; i++) { + // 사용할 연산자가 남아있지 않으면, 사용 불가 + if (expression[i] == 0) {//연산자 개수가 없으면 반복문으로 돌아가기 + continue; + } + + // 연산자 사용 + expression[i]--;//연산자 개수 하나 줄이기 + int new_sum = 0; + switch (i) { + case ADD://i가 0이면 + new_sum = curr_val + nums[cnt + 1];//뽑은 연산자 +1 위치에 있는 값 더하기 + break; + case SUB://i가 1이면 + new_sum = curr_val - nums[cnt + 1];//뽑은 연산자 +1 위치에 있는 값 빼기 + break; + case MUL://i가 2이면 + new_sum = curr_val * nums[cnt + 1];//뽑은 연산자 +1 위치에 있는 값 곱하기 + break; + case DIV://i가 3이면 + new_sum = curr_val / nums[cnt + 1];//뽑은 연산자 +1 위치에 있는 값 나누기 + break; + } + + // 다음 연산자 선택 + backtrack(cnt + 1, new_sum);//재귀적으로 반복 + + // 연산자 반납 + expression[i]++; + } +} + +/** + * 모든 연산자 조합을 시도해보면서 최대값과 최솟값을 찾는다. + * 모든 연산자 조합을 만들기 위해 가장 왼쪽에 들어갈 연산자부터 하나씩 선택한다. + */ +int main() { + // 입력 + cin >> n;//수의 개수 입력받기 + for (int i = 0; i < n; i++) {//입력받은 수의 개수만큼 + cin >> nums[i];//숫자 입력받기 + } + for (int i = 0; i < EXP_NUM; i++) {//연산자 개수 입력받기 + cin >> expression[i]; + } + + // 연산 + backtrack(0, nums[0]); + + // 출력 + cout << max_val << '\n' << min_val; + + return 0; +} \ No newline at end of file From 86a9239c31cec6ff181542af9019ba97dbcc5bba Mon Sep 17 00:00:00 2001 From: rahaaaiii Date: Sun, 12 Nov 2023 16:45:04 +0900 Subject: [PATCH 3/3] Create 15665.cpp --- .../15665.cpp" | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 "09_\353\260\261\355\212\270\353\236\230\355\202\271/15665.cpp" diff --git "a/09_\353\260\261\355\212\270\353\236\230\355\202\271/15665.cpp" "b/09_\353\260\261\355\212\270\353\236\230\355\202\271/15665.cpp" new file mode 100644 index 0000000..ec432cf --- /dev/null +++ "b/09_\353\260\261\355\212\270\353\236\230\355\202\271/15665.cpp" @@ -0,0 +1,47 @@ +// 15665번 N과 M(11): https://www.acmicpc.net/problem/15665 +#include +#include +#include + +using namespace std; + +set numbers; // 입력 받은 수 +vector sequence; // 출력할 수열 + +/** + * 입력 받은 수에서 중복수열을 만든다. + * + * m: 수열의 길이 + * cnt: 현재 뽑은 수의 개수 +*/ +void backtracking(int m, int cnt) { + // 재귀 호출 종료 조건: m개의 수를 모두 뽑음 + if (cnt == m) {//현재 뽑은 수의 개수가 수열의 길이와 같다면 + // 수열 출력 + for (int i = 0; i < m; i++) + cout << sequence[i] << ' ';//수열 출력하기 + cout << '\n'; + return; + } + // 중복을 허용해서 하나씩 수를 뽑아 수열에 저장 + for (auto num: numbers) { + sequence[cnt] = num;//수열에 값 저장 + backtracking(m, cnt + 1);//재귀적으로 반복 + } +} + +int main() { + // 입력 + int n, m; + cin >> n >> m;//n과 m값 입력받기 + while (n--) {//n이 0이 아니라면 + int num; + cin >> num;//값 입력ㅂㄷ기 + numbers.insert(num);//입력받은 수 집합에 값 집어넣기 + } + // 초기화 + sequence.assign(m, 0); + // 연산 + backtracking(m, 0); + return 0; +} \ No newline at end of file