본문 바로가기

알고리즘

Boj 2003 c++ 투 포인터의 장점

처음 제출한 코드는 다음과 같다.

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int main(){
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int N, M;

    cin>>N>>M;

    vector<int> v;


    for(int i=0; i<N; i++){
            int num;
        cin>>num;
        v.push_back(num);
    }

    int L=0, R=0;

    int ans=0;
    while(R<N){
       long long sum=0;
       for(int i=L; i<=R; i++){
        sum+=v[i];
       }
    if(sum>=M){
        L++;}
    else if(R==N-1)
        break;
    else
        R++;
    if(sum==M)
        ans++;
    }
    cout<<ans;

}

이 코드를 제출해서 맞기는 했다. 하지만 투포인터의 장점을 전혀 이용하지 않은 중첩 반복문과 헷갈리는 논리 형식으로 인해 코드가 더 개선될 수 있음을 느꼈다. 때문에 매번 반복문을 돌리는 대신, sum의 값을 초기화하지 않아 누적합의 형식을 지키되, 조건에 따라서 누적합에 v[L++]값을 빼거나 v[R++]값을 더하여 투포인터 알고리즘을 활용했다.

#include<iostream>
#include<vector>

using namespace std;

int main(){
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int N, M;

    cin>>N>>M;

    vector<int> v(N);


    for(int i=0; i<N; i++){
        cin>>v[i];
    }


    int L=0, R=0, ans=0;//투포인터 초기값
    long long sum=0;

    while(1){
        if(sum>=M)//무한루프 방지 위해서 등호를 꼭 너허주어야 한다.
            sum-=v[L++];//합이 크면 시작값 빼주기
        else if(R==N)
            break;    //끝값이 배열의 끝에 도달하면 끝내기

        else
            sum+=v[R++];//합이 작으면 앞에 값 추가하기

        if(sum==M)
            ans++;
    }


    cout<<ans;

}

논리 흐름을 자연스럽게 하기 위해서는 조건을 while문 안으로 빼줘야 한다. R++이 진행된 후, 다음 루프에서 반복문이 종료되도록 설계한다. 또한 대소비교에서 등호를 넣지 않으면 무한루프에 빠질 수 있기 때문에 순서를 잘 배치해야 한다.

'알고리즘' 카테고리의 다른 글

Boj 11725 c++트리의 부모 찾기  (0) 2025.05.30
Boj 15971 c++ 두 로봇  (0) 2025.05.28
Boj 3896 c++ 소수사이 수열  (0) 2025.05.27
Boj 1990 c++소수인 팰린드롬  (0) 2025.05.26
Boj 1747 c++ 소수&팰린드롬  (0) 2025.05.25