오름차순으로 나열된 구간

gcoco·2023년 5월 9일
0

안녕하세요! 구간탐색에 항상 어려움을 겪는 GCOCO입니다!

항상 구간 관련되서 최소값이나 최대값 또는 연속된 구간을 탐색하는 것이 많이 어렵게 느껴지더라구요. 허헣...
뭔가 search(argument) 이런식으로 딱 함수 하나로 챡챠챡 여깄습니다 master. 하고 제공해주는 함수가 있으면
좋겠다는 생각이 드는군요!


잡설 한 COOKIE🍪

사진은 농구를 물어보지만 저 GCOCO, 방문객님에게 묻고싶습니다.

여행... 좋아하시나요..?

날은 점점 더워지고 무거운 취업준비는 저를 짓누르는만큼 홀가분히 여행을 떠나고 싶군요!

제 처음이자 마지막 해외여행은 일본여행이었는데요, 그때 2주간 함께 다녀온 친구와의 추억은 아직도 저를

때때로 즐거움에 젖게 하는 참 좋은 기억입니다.

상황이 여행을 허락하진 않지만, 간단한 산책정도는 괜찮잖아!?

여러분도 집 근처의 산책이라도 해보시는것을 추천드립니다!

사람을 구경하고 바람을 맞는건 생각보다 큰 기분환기를 이끌어 준답니다.

아무튼, 저를 괴롭힌 그 문제 한 번 보시죠!


문제

정수의 수열이 주어졌을 때, 오름차순으로 나열된 최대 연속구간의 개수와 그 구간에 포함된 모
든 정수의 합을 계산하는 프로그램을 작성하시오.

정수의 개수는 최소 0 이며 최대 1,000 이다


입력

3
20 1 2 3 3 4 3 4 5 5 6 6 7 6 5 4 5 3 6 2 8
5 1 2 3 4 5
5 5 4 3 2 1

출력

5 77
1 15
0 0

코드, 같이 보시죠!

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

using namespace std;

int main() {
    int t;
    cin >> t;
    for (int i = 0; i < t; i++) {
        int answer = 0;//정답 기록
        int count = 0;//구간 기록
        int pos = 0;//index
        int num;
        cin >> num;
        vector<int> v(num, 0); //구간 탐색을 위한 vector
        //v의 원소 입력
        for (int j = 0; j < num; j++) {
            int element;
            cin >> element;
            v[j] = element;
        }
        vector<int> tmp;//합계산을 위한 vector tmp
        //v의 오름차순이 있는 구간 탐색
        while (pos < num) {
            int now = v[pos];//현재 원소
            //tmp가 비면 채워주기
            if (tmp.empty())
                tmp.emplace_back(now);
            //tmp에 들어있는 마지막 값과 now를 비교
            //now가 크거나 같다면 tmp에 추가
            else if (tmp.back() <= now) {
                tmp.emplace_back(now);
            }
            //now가 작다면
            else {
            	//tmp의 size가 1이라면 연속된 구간이 없음
                if (tmp.size() == 1) {
                    tmp.clear();
                    continue;
                }
                else {
                	//tmp size가 1보다 크면 연속된 구간이 존재
                    //합계산
                    for (auto i : tmp) {
                        answer += i;
                    }
                    tmp.clear();
                    count++;
                    //다시 탐색의 필요가 있기에 index 1 줄이기
                    pos--;
                }
            }
            pos++;
        }
        //tmp에 유효한 구간이 남아있다면 정산해주기
        if (!tmp.empty() && tmp.size() != 1) {
            for (auto i : tmp) {
                answer += i;
            }
            count++;
        }
        cout << count << ' ' << answer << endl;
    }
    return 0;
}

좀 지저분 하죠,,,??? 나름 최선을 다한 코드입니다.

코드의 step은 다음과 같습니다.

  1. vector v를 이용해 입력을 저장하는 vector를 만든다.
  2. vector tmp를 이용하여 tmp가 비었다면 값을 1개 채워준다.
  3. 이후 오름차순 규칙에 의해 값을 집어넣는다.
  4. 규칙에 어긋나면 tmp의 size를 검사해 size가 1이라면 비우고 재탐색을 시작한다.
  5. tmp의 size가 1이 아니라면 연속된 구간이 존재한다는 것이고 이를 계산하여 answer과 count를 업데이트 한다.

이 정도가 되겠습니다!

좀 더 깔끔히 코드를 작성할 수 있는 방법을 고민 해봐야겠군요.😣


작은 도움이 되었길 바라며, 포스팅을 마치겠습니다!

profile
그코코 입니다.

0개의 댓글