728x90
분류
- 구현
- 시뮬레이션
문제
https://www.acmicpc.net/problem/20055
풀이
저 1,2,3,4번을 순서대로 하기만하면된다.
근데, 특히 회전을 직접 한칸씩 옮겨서 구현하는 것은 매우 비효율적(코드1번)이기 때문에 포인터를 사용(코드2번)해야한다.
(코드 1번)
( 회전을 인덱스로 구현하는 것 까지는 알겠는데, 로봇배열이랑 내구성배열을 따로따로하려니 헷갈림 )
포인트는
1. 구조체로 해당 인덱스에 로봇의 여부 / 내구성을 저장하게 구현하는 것이고,
2. 인덱스 포인터를 사용하기
배열을 이동시키나, 포인터만 앞으로(--pos) 이동시키나 같다.
(이때 회전벨트이므로, 원형 큐처럼 구현해야한다. 하지만 원형 큐는 pos++였던 점에서 코드가 약간 다름)
3. STEP2 : 가장 먼저 벨트에 올라간 로봇부터 검사해야 하는 것은, 내리는 위치에 가까운 것부터 이동시키는 것
코드
배열의 이동으로 구현
/*
* 로봇 / 칸
*
* 올리는 위치 : 1
* 내리는 위치 : N
*
* <칸의 내구도>
* 내구도(i칸) : Ai
* 내구도 감소 (-1) : 1. 올리는 위치에 로봇을 올림 2. 로봇이 이동해서 해당 칸에 올라옴
*
* 목적 : 로봇을 1칸에 올려 -> 한칸씩 움직여 반대편으로
*
* 조건 :
* 칸의 내구도가 0이면 해당칸으로 이동 불가능
* 1칸당 로봇 1개까지만 가
*
*
*
*
*/
#include <iostream>
#include <vector>
using namespace std;
vector<int> dur;
vector<bool> robot;
int num = 0;//내구도가 0인 칸의 수
int main() {
int N, K;
cin >> N >> K;
dur.assign(2 * N + 1, 0); // 0 1 ~ 2N까지
robot.assign(N + 1, false); // 0 1 ~ N까지
for (int i = 1; i < 2 * N + 1; i++) { //1번칸부터 2n칸까지
cin >> dur[i];
}
int count = 0;
while (num < K) {
//1. 컨베이어 벨트의 회전
dur[0] = dur[2 * N];
//한칸씩 이동
for (int i = 2 * N; i > 0; i--) {
//1) durability 변경
dur[i] = dur[i - 1];
//2) 위에 올라간 로봇
if (i < N) {
//한칸씩 땡기는데 1)N에 도달하는 애는 버리기 2) 1은 false (0은 언제나 false라 이미 ㄱㅊ)
robot[i] = robot[i - 1];
}
}
//N에 누군가 도달했다면 버려주기
if (robot[N]) robot[N] = false;
//2. 로봇의 이동 -> 가장 먼저 벨트에 올라간 로봇부터 움직여야하는데 (뒤부터하면될거같은디..)
//한칸씩 이동
for (int i = N; i > 0; i--) {
if (robot[i - 1] && !robot[i] && dur[i] >= 1) { //해당칸에 로봇 x , 내구성 1이상
robot[i] = true;//어쩌피 전칸에 로봇이 있을떄만 돌아가서 이렇게 해도될듯?
robot[i - 1] = false;
dur[i]--;
if (dur[i] == 0) num++;
}
}
if (robot[N]) robot[N] = false;
//3. 배치
if (dur[1] != 0) {
robot[1] = true;
dur[1]--;
if (dur[1] == 0) num++;
}
count++;
}
cout << count;
}
인덱스 포인터의 이동으로 구현
#include <iostream>
#include <vector>
using namespace std;
struct info { //내구도와 로봇 존재 여부
int power;
bool is_on;
};
vector<info> belt; //컨테이너 벨트 정보(내구도, 로봇 여부)
int zero_power = 0; //내구도가 0인 벨트 칸의 개수
int minusPosition(int pos, int n) { //인덱스 감소(한칸앞으로 이동)
if (--pos >= 0)
return pos;
return pos + 2 * n;
}
void second(int end, int start, int n) {
int cur = end;
while (cur != start) { //범위가 달라서 작은거로 하면안됨
cur = minusPosition(cur, n);
int next = (cur + 1) % (2 * n);
if (!belt[next].is_on && belt[next].power >= 1 && belt[cur].is_on) {
belt[cur].is_on = false;
belt[next].power--;
if (next != end) belt[next].is_on = true; // 다음칸이 end칸이면 옮기면안됨
if (belt[next].power == 0) zero_power++;
}
}
}
void third(int start) {
if (belt[start].power != 0) {
belt[start].is_on = true;
belt[start].power--;
if (belt[start].power == 0)
zero_power++;
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, k;
cin >> n >> k;
belt.assign(2 * n, {0, false});
for (int i = 0; i < 2 * n; i++) {
cin >> belt[i].power;
}
int step = 0;
int start = 0;
int end = n - 1;
while (zero_power < k) {
//1. 벨트 이동
start = minusPosition(start, n);
end = minusPosition(end, n);
if (belt[end].is_on)
belt[end].is_on = !belt[end].is_on;
//2. 로봇이동
second(end, start, n);
// 3.로봇 배치
third(start);
step++;
}
cout << step;
return 0;
}
728x90
'Algorithm > BaekJoon' 카테고리의 다른 글
[3190] 뱀 (0) | 2021.10.09 |
---|---|
[2529] 부등호 (0) | 2021.10.09 |
[20302] 민트초코 (0) | 2021.09.27 |
[2841] 외계인의 기타 연주 (0) | 2021.09.27 |
[2493] 탑 (0) | 2021.09.24 |