boj 1644번 문제의 풀이중 만나게된 런타임에러(OutOfBounds)상황에 대하여.
#include <bits/stdc++.h>
using namespace std;

int n;
vector<int> sieve(int n){
    vector<int> primes;
    vector<bool> check(n+1,true);
    check[1]=false;
    for(int i=2;i*i<=n;i++){
        if(!check[i]) continue;
        for(int j=2*i;j<=n;j+=i)
            check[j]=false;//여길 자꾸 i로 작성하는데, j이다. 주의하도록 하자.
    }
    for(int i=2;i<=n;i++)
        if(check[i]) primes.push_back(i);
    return primes;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>n;
    vector<int> primes=sieve(n);
    primes.push_back(0);
    int ans=0, st=0,en=1,tot=primes[0];
    while(1){
        if(tot==n) ans++;
        if(tot<=n) tot+=primes[en++];
        if(tot>n) tot-=primes[st++];
        if(en==int(primes.size())) break;
    }
    cout<<ans;
}

처음에 코드를 이렇게 작성하고나서 제출했을때, out of bounds를 일으켜서 통과하지 못하였다. 

아무래도 primes에서 포인터를 옮겨가면서 계산을 할때, 그때에 원소들의 인덱스를 벗어나는것 같은 생각이 들었는데, 

처음에 작성한 코드를 볼때는 무엇 때문에 어디에서 인덱스를 벗어나는지 찾을 수 없었다. 

#include <bits/stdc++.h>
using namespace std;

int n;
vector<int> sieve(int n){
    vector<int> primes;
    vector<bool> check(4000001,true);
    check[1]=false;
    for(int i=2;i*i<=4000000;i++){
        if(!check[i]) continue;
        for(int j=2*i;j<=4000000;j+=i)
            check[j]=false;//여길 자꾸 i로 작성하는데, j이다. 주의하도록 하자.
    }
    for(int i=2;i<=4000000;i++)
        if(check[i]) primes.push_back(i);
    return primes;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>n;
    vector<int> primes=sieve(n);
    primes.push_back(0);
    int ans=0, st=0,en=1,tot=primes[0];
    while(1){
        if(tot==n) ans++;
        if(tot<=n) tot+=primes[en++];
        if(tot>n) tot-=primes[st++];
        if(en==int(primes.size())) break;
    }
    cout<<ans;
}

그래서 이런식으로 pirmes를 애초에 문제에서 제시한 4'000'000개까지 모두 계산해서 primes에 넣어놓고, 그 후에 

코드를 제출하니 out of bounds를 피할 수 있었다. 

일단 이 경우에 대해서는 지속적으로 첫번째 풀이를 작성했을때 어떤 부분에서 out of bounds가 되어서 문제를 발생시키는지, 

primes의 투 포인터를 옮겨가면서 문제가 발생한게 맞는지 다시 한번 생각해보도록 하자. 

 

  Comments,     Trackbacks