void solve1(vector& weapon, map& cache, list& picked, int K, int idx, int flag, int& ret){
/*
list::iterator it;
cout << "PICKED : ";
for (it = picked.begin(); it != picked.end(); it++){
cout << *it << " ";
}
if (cache.size() == K){ cout << "ret++"; }
cout << endl;
*/
int N = weapon.size();
if (idx >= N){ return; }
if (picked.size() <= 0){ return; }
if (cache.size() < K){ return; }
if (cache.size() == K){
ret++;
int backup = picked.front();
cache[backup]--;
if (cache[backup] <= 0){ cache.erase(backup); }
picked.pop_front();
solve1(weapon, cache, picked, K, idx, -1, ret);
picked.push_front(backup);
cache[backup]++;
if (flag != -1){
if (idx + 1 < N){
int val = weapon[idx + 1];
cache[val]++;
picked.push_back(val);
solve1(weapon, cache, picked, K, idx + 1, 0, ret);
}
}
}
if (cache.size() > K){
int front = picked.front();
cache[front]--;
if (cache[front] <= 0){ cache.erase(front); }
picked.pop_front();
solve1(weapon, cache, picked, K, idx, 0, ret);
}
}
int solve2(vector& weapon, int N, int K){
int ret = 0;
if (N < K){ return 0; }
if (K == 0){ return 0; }
map cache;
list picked;
int idx = -1;
for (int i = 0; i < N; i++){
int val = weapon[i];
cache[val]++;
picked.push_back(val);
if (cache.size() == K){ idx = i; break; }
}
if (idx == -1){ return 0; }
solve1(weapon, cache, picked, K, idx, 0, ret);
return ret;
}
int main(){
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T--){
int N, K;
cin >> N >> K;
vector weapon;
for (int i = 0; i < N; i++){
int buf;
cin >> buf;
weapon.push_back(buf);
}
cout << solve2(weapon, N, K) << endl;
}
system("pause");
}
~~~
iyaa
https://algospot.com/judge/problem/read/HOMURAARSENAL
예제 기준 알고리즘 설명입니다.
7 2
1 2 2 4 2 3 1
PICKED : 1 2 ret++
PICKED : 2
PICKED : 1 2 2 ret++
PICKED : 2 2
PICKED : 1 2 2 4
PICKED : 2 2 4 ret++
PICKED : 2 4 ret++
PICKED : 4
PICKED : 2 2 4 2 ret++
PICKED : 2 4 2 ret++
PICKED : 4 2 ret++
PICKED : 2
PICKED : 2 2 4 2 3
PICKED : 2 4 2 3
PICKED : 4 2 3
PICKED : 2 3 ret++
PICKED : 3
PICKED : 2 3 1
PICKED : 3 1 ret++
PICKED : 1
9
cache의 사이즈가 K보다 작을때 -> 무조건 함수 return으로 끝냄
K일때 -> picked(선택한것 저장하고 있는 list)의 front를 뺀것도 돌리고, tail에 다음 idx의 value를 붙인것도 돌림
K보다 클때 -> 무조건 front를 뺀걸 돌림
이러한 알고리즘으로 풀고있고, 수제작 및 스캐폴딩 테스트케이스도 정상적으로 답을 반환합니다만, 알고스팟에서 메모리 엑세스 or 버퍼 오버플로우 라고 오류가 뜨더군요..
의심가는 모든곳을 기저 사례로 추가했는데도 불구하고 메모리 오류가 나니 당황스럽습니다. (익시드라면 로직상의 오류겠지만요..)
아래는 코드입니다. 참고하시고 어디가 오류인지 알려주시면 감사하겠습니다.
~~~ c++
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void solve1(vector& weapon, map& cache, list& picked, int K, int idx, int flag, int& ret){::iterator it;
/*
list
cout << "PICKED : ";
for (it = picked.begin(); it != picked.end(); it++){
cout << *it << " ";
}
if (cache.size() == K){ cout << "ret++"; }
cout << endl;
*/
int N = weapon.size();
}& weapon, int N, int K){ cache; picked;
int solve2(vector
int ret = 0;
if (N < K){ return 0; }
if (K == 0){ return 0; }
map
list
int idx = -1;
for (int i = 0; i < N; i++){
int val = weapon[i];
cache[val]++;
picked.push_back(val);
if (cache.size() == K){ idx = i; break; }
}
if (idx == -1){ return 0; }
solve1(weapon, cache, picked, K, idx, 0, ret);
return ret;
} weapon;
int main(){
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T--){
int N, K;
cin >> N >> K;
vector
for (int i = 0; i < N; i++){
int buf;
cin >> buf;
weapon.push_back(buf);
}
cout << solve2(weapon, N, K) << endl;
}
system("pause");
}
~~~
10년 전