#include <bits/stdc++.h>
using namespace std;
int n, m;
// int a[10'005];
vector<int> v;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m;
for(int i=0; i<n; i++){
int t;
cin>>t;
v.push_back(t);
}
v.push_back(0);
int ans=0,st=0,en=1,tot=v[0];
//a[n]==0; 전역변수로 선언했기 때문에 초기화가 0으로 되어있어서 불필요한 코드.
while(1){
if(tot==m) ans++;
if(tot<=m) tot+=v[en++];
if(tot>m) tot-=v[st++];
if(en==int(v.size())) break;
}
cout<<ans;
}
/*
이 버전의 경우는 처음에 array로 풀었다가 통과하지 못해서, vector로 버전을
바꾸어서 제출한 코드이다. 이 코드는 기존에 통과했었던 boj 1644: 소수의 연속합
문제의 풀이 로직을 그대로 가져와서 풀어본 형태인데, 처음에 배열 버전으로 바꾸었다가
통과하지 못해서 그대로 백터 형태로 변형해서 제출했을때 통과하였다.
*/
위의 경우는 내가 처음에 작성한 array 버전에서 사용한 로직을 그대로 사용하는 vector를 이용한 풀이이다. 이 풀이의 경우는
boj 1644번: 소수의 연속합 풀이에 사용한 vector를 사용한 풀이의 로직을 그대로 사용해서 작성해본 풀이인데, 이 풀이를 기반으로 처음에는 array를 사용한 풀이방법을 제출해서 통과하지 못하였다.
그 풀이를 첨부해보면,
#include <bits/stdc++.h>
using namespace std;
int n, m;
int a[10'005];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m;
for(int i=0; i<n; i++) cin>>a[i];
int ans=0,st=0,en=1,tot=a[0];
//a[n]==0; 전역변수로 선언했기 때문에 초기화가 0으로 되어있어서 불필요한 코드.
while(1){
if(tot==m) ans++;
if(tot<=m) tot+=a[en++];
if(tot>m) tot-=a[st++];
if(en==n) break;
}
cout<<ans;
}
/*
이 풀이의 경우, boj 1644번 풀이의 방법을 vector 형태가 아닌 array 형태로 바꾸어서
제출해보았는데, 통과하지 못한 풀이. 이 이후에 vector로 다시 작성해서 통과하긴 했는데
현재 array 버전과 vector 버전에서의 차이가 어느 부분에서 발생해서 통과하지 못하는지에 대해서
찾아보아야 함.*/
/*예제의 입출력에 대해서는 정상적으로 동작하는데,
아무래도 n==1일때, 혹은 n=10'000 일대 처럼 양 극단에서 예상과는
다른 동작을 하는게 아닌가 싶음.
*/
위와 같다.
위 코드가 통과하지 않기에, vector버전으로 교체하여 제출하였고 통과하게 된 상황인데, 이때에
array버전 코드의 문제가 무엇일까 생각해보았을때, 예제입력으로 주어진 내용들에 대해선 원하는 예제 출력이 나오기 때문에,
양 극단에서 문제가 발생하지 않을가 싶은 생각이 들었다. n==1 이거나 n==10'000 같은 경우들에서 문제가 발생할 수 있겠다는 생각이 들었고, 예시 입력으로
1 2
2
를 입력해보았을때,
이와 같은 에러 메세지를 얻을 수 있었다.
이때에 zsh: bus error의 경우는 처음 보는 메세지이기 때문에 이에 대해서 검색해보았다.
결국 내가 작성한 코드의 형태와, 예제 코드의 입력 내용과, 위에서 언급된 bus error의 내용에 해당할 수 있는 경우들을 보았을때,
en=1로 시작하는 부분과 en==n 를 판별하는 부분에서 문제가 발생할 수 있겠다는 생각이 들었다.
+++++++++++++++++++++++++++++
위와 같은 내용에 대해서 생각해보다보니 내린 판단으로는,
st=0, en=1 로 시작을 하는데, 이 경우에 while문 내부에서의 while문을 탈출시키게 만드는 판단 부분이
if(e==n) break; 형태로 잡혀있는데, 여기서 e==n+1 형태로 잡아주어야 통과할 수 있는 코드가 된다.
이때에 vector형태의 풀이는 en을 갯수로 생각하면 이해하기 편하고, array 형태의 코드는 en을 인덱스로 생각하면 이해하기 편하다고 본다.
이와 관련하여서 변경한 코드를 주석으로 해석을 작성하여서 첨부하여본다. vector를 이용한 풀이와 array를 이용한 풀이를 사용할때 en과 while문 탈출 판단부를 잘 고려해서 코드를 작성해보도록 하자.
#include <bits/stdc++.h>
using namespace std;
int n, m;
int a[10'005];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m;
for(int i=0; i<n; i++) cin>>a[i];
int ans=0,st=0,en=0,tot=a[0];
//a[n]==0; 전역변수로 선언했기 때문에 초기화가 0으로 되어있어서 불필요한 코드.
while(1){
if(tot==m) ans++;
if(tot<=m) tot+=a[++en];
if(tot>m) tot-=a[st++];
if(en==n) break;/*vector코드 형태와 다른부분은 en이 의미하는 바가
vector풀이는 갯수, array 풀이는 인덱스 라는 상황이라는 것이라고 생각된다.
이 경우 array 풀이에서 올바른 경우를 출력하려면, en=0부터 시작을 하거나
혹은 en=1로 시작을 한뒤에 맨 마지막 while문 탈출 부분을 vector처럼 갯수
형태로 판단하는게 아니라 인덱스값으로 고려해서 판단해주어야 올바른 코드가 된다고
보여진다. */
//그래서 en=0으로 시작해서 en==n으로 판단하거나,
//en=1로 시작해서 en==n+1로 해야 옳바른 arrary 를 이용한 풀이가 될것이다.
}
cout<<ans;
}
/*
en=1 tot=a[0] en==n+1로 판단
en=0 tot=0 tot+=a[++en] en==n로 판단*/
'알고리즘 > BOJ' 카테고리의 다른 글
boj 7785번 문제를 통해 접하게된 unordered_set과 sort에 관하여. (0) | 2023.06.20 |
---|---|
boj 22862번 문제를 통해 접하게된 짝수일때, 홀수일때 수를 경우의 수를 더하는 방법에 대하여. (0) | 2023.06.18 |
boj 1644번 문제의 풀이중 만나게된 런타임에러(OutOfBounds)상황에 대하여. (0) | 2023.06.16 |
boj 1806번 문제를 통해서 본 for 문 속에서 st++;을 추가한 코드의 실행에서의 st의 증가에 관하여. (0) | 2023.06.15 |
boj 7453번 문제를 통해 보는 int와 long long 으로 선언했을때의 시행 시간의 차이와 cache hit rate를 높이는 방법에 대하여. (0) | 2023.06.13 |