https://www.acmicpc.net/problem/31747
#문제 간단 정리
2학년과 1학년이 섞인 줄에서
가장 앞에있는 2학년과 1학년을
하나씩 없에는 기능을 구현하는
구현 + 시뮬레이션 문제
#문제 해결 방법
우선 나이브하게
그냥 1학년과 2학년을 k만큼 탐색해서
벡터에서 제거해주는 나이브한 로직을 생각 해 낼 수 있는데
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
vector<int> line(n);
for (int i = 0; i <n; i++) {
cin >> line[i];
}
int time = 0;
while (!line.empty()) {
bool grade1 = false;
bool grade2 = false;
int grade1Index = 0;
int grade2Index = 0;
int checkLength = line.size();
checkLength = min(k, checkLength);
for (int i = 0; i < checkLength; i++) {
if (line[i] == 1 && grade1 == false) {
grade1Index = i;
grade1 = true;
}
if (line[i] == 2 && grade2 == false) {
grade2Index = i;
grade2 = true;
}
}
if (grade1 && grade2) {
if (grade1Index < grade2Index) {
line.erase(line.begin() + grade2Index);
line.erase(line.begin() + grade1Index);
}
else {
line.erase(line.begin() + grade1Index);
line.erase(line.begin() + grade2Index);
}
}
else if (grade2) {
line.erase(line.begin() + grade2Index);
}
else if (grade1) {
line.erase(line.begin() + grade1Index);
}
;
time++;
}
cout << time << '\n';
return 0;
}
벡터에서 제거하는 부분에서도 시간초과가 날 수 있지만
그전에 간단하게 만약 k = n 이라고 하게 되면
항상 n개를 탐색하게 되어서 매우 시간복잡도 가 크게 된다
때문에 나는
1학년과 2학년의 위치를
덱에 넣고
얼마만큼 빠져나간지 알도록 인덱스를 사용하였다
현재 줄에서 빠져나간 만큼 인덱스를 올려서 인덱스를 참조하도록 하였다.
여기서 1학년 덱과 2학년 덱을 조사해서 맨 앞에 있는 값이
인덱스 + k 의 값 이하의 값을 가지고 있다면
덱에서 pop 해주고 인덱스를 올려 줬다.
이렇게 남은 1학년과 2학년의 숫자와
줄의 길이를 빠르게 추적 가능하다
정확히 이런 기능을 어떻게 구현할지 물어보는 문제라고 볼 수 있겠다.
아 물론 덱을 안쓰고 벡터를 역순으로 집어 넣는다던가 하는 식으로 덱을 안써도 할 수 있겟지만
직관적으로 풀려고 덱을 사용하였다.
#전체 코드
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <climits>
#include <deque>;
using namespace std;
int main() {
int n, k;
cin >> n >> k;
deque<int> line(n);
deque<int> grade1;
deque<int> grade2;
int lineSize = line.size();
for (int i = 0; i < n; i++) {
cin >> line[i];
if (line[i] == 1) {
grade1.push_back(i);
}
else {
grade2.push_back(i);
}
}
int time = 0;
int index = 0;
while (index < line.size()) {
//남은 인덱스 확인
int checkLength = index + k - 1;
checkLength = min(lineSize -1 , checkLength);
if (!grade1.empty() && grade1.front() <= checkLength) {
index++;
grade1.pop_front();
}
if (!grade2.empty() && grade2.front() <= checkLength) {
index++;
grade2.pop_front();
}
time++;
}
cout << time << '\n';
return 0;
}
'[백준] > C++' 카테고리의 다른 글
백준 16405번 Birthday Boy [C++] (1) | 2024.09.21 |
---|---|
백준 4040번 Polar Bear [C++] (1) | 2024.09.21 |
백준 7479번 Greatest Product [C++] (0) | 2024.09.13 |
백준 16624번 Bingo Ties [C++] (0) | 2024.09.13 |
백준 9764번 서로 다른 자연수의 합 [C++] (0) | 2024.09.13 |