CPP01

JUSTICE_DER·2023년 3월 27일
0

⏲ CPP - 코딩테스트

목록 보기
3/41

1. 10797

해결

#include <iostream>
using namespace std;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int num;
    int count = 0;
    int car_num;

    cin >> num;

    for (int i = 0; i < 5; i++)
    {
        cin >> car_num;
        if(car_num == num){
            count++;
        }
    }

    cout << count;
    
    return 0;   
}

풀이

ios::sync_with_stdio(0);
cin.tie(0);
개념을 곧바로 사용해보았고,

Java처럼 한 줄씩 읽는게 아니라 Tokenize도 할 필요가 없었고,
Integer.parseInt(st.nextToken())

C처럼 어디에 저장할지 길게 쓸 필요도 없었다.
scanf("%d", &temp)

그리고 endl 대신 \n를 사용해보았다.

2. 2576

해결

#include <iostream>
using namespace std;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int num;
    int odd_sum = 0;
    int min=99; //주어지는 자연수는 100보다 작다.

    for (int i = 0; i < 7; i++)
    {
        cin >> num;
        if (num % 2 == 1)
        {
            if (num <= min)
            {
                min = num;
            }
            odd_sum += num;
        }
    }
    if(odd_sum > 0){
        cout << odd_sum << "\n"
         << min;
    }
    else{
        cout << -1;
    }
    

    return 0;
}

풀이

입력으로 7개의 정수만 주어진다던가,
주어지는 자연수가 100보다 작다는 조건이 문제를 더 쉽게 만들었다.
아직 상당히 쉽다. cin cout을 적응하는데 초점을 맞추고 있다.
위처럼 다양한 자료형을 섞어서 연속으로 붙여서 출력하는 것도 가능하고,
그냥 숫자만 달랑 써도 정상 출력 된다는 것을 시험해보았다.

3. 10818

시도

위처럼 코드를 작성하니 문제가 생겼다.
그 이유는 14번줄이다.
cin을 하여 min에 넣고, 그 값을 max에 추가 입력 없이 곧바로 넣을 줄 알았는데,
2번 넣는 동작을 하였다.
31번줄 cout도 그렇다면, 한번에 수행하는게 아니라, cout<<min, cout <<" ", cout <<max를 수행하는 것일듯 하다.

해결

#include <iostream>
using namespace std;

int main(){
    ios::sync_with_stdio(0);
    //cin.tie(0);

    int N;
    int num;
    int min;
    int max;

    cin >> N;

    cin >> min; //가장 첫번째 원소를 min, max값으로 둔다
    max = min;

    for (int i = 1; i < N; i++)
    {
        cin >> num;
        if(num >= max){
            max = num;
        }
        else{
            if(num<=min){
                min = num;
            }
        }
    }

    cout << min << " " << max;
    

    return 0;   
}

풀이

cin >> min; //가장 첫번째 원소를 min, max값으로 둔다 부분이 핵심이다.
그 외에는 쉬웠고, cin과 cout의 동작원리를 어느정도 알았다.

4. 2506

해결

#include <iostream>
using namespace std;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int N;
    int answer;
    int this_score = 0; //해당 문제의 정답, 콤보시스템
    int sum_score = 0;

    cin >> N;
    for (int i = 0; i < N; i++)
    {
        cin >> answer;
        if(answer==1){  //정답인 경우,
            this_score++;
            sum_score+=this_score;
        }
        else{
            this_score = 0;
        }
    }
    cout << sum_score;
    

    return 0;   
}

풀이

콤보처럼 연속으로 맞추는 경우, 점수가 증가한다는게 신선했고,
this_score로 관리를 했다.
해당 변수의 처리 외에 고민할것은 없었다.

5. 2484

시도

#include <iostream>
using namespace std;

int main()
{
    //ios::sync_with_stdio(0);
    cin.tie(0);

    int N;
    int one_roll;
    int dice_Result[7] = {};
    int count;

    // 예외상황들에 대한 변수
    bool two_two = false;
    int one_one_one_one = 0;
    int max = 0;

    cin >> N;
    int tmp_get = 0;
    int max_get = 0;

    // N명의 사람들마다
    for (int i = 0; i < N; i++)
    {
        // 4개의 주사위를 던진다.
        for (int roll; roll < 4; roll++)
        {
            //scanf("%d", &one_roll);
            cin >> one_roll; // 이부분이 이상함.
            dice_Result[one_roll]++;
            cout << "roll : " << roll << "num :" << one_roll << "\n";
        }
        // 1~6의 숫자가 몇개씩 나왔는지 판단하여, 상금을 부여한다.
        for (int num = 1; num <= 6; num++)
        {
            if (dice_Result[num] >= 1)
            {
                if (dice_Result[num]  >= 2)
                {
                    if (dice_Result[num]  >= 3)
                    {
                        if (dice_Result[num]  == 4)
                        {
                            tmp_get += 50000 + num * 5000;
                        }
                        else
                        {
                            tmp_get += 10000 + num * 1000;
                        }
                    }
                    else
                    {
                        if (two_two == false)
                        {
                            tmp_get += 2000 + num * 500;
                            two_two = true;
                        }
                        else
                        {
                            tmp_get += num * 500;
                        }
                    }
                }
                else
                {
                    one_one_one_one ++;

                    if(max < num){
                        max = num;
                    }
                    if(one_one_one_one == 4){
                        tmp_get = max * 100;
                    }
                }
            }
            if(max_get < tmp_get){
                max_get = tmp_get;
            }

            //주요 값들 초기화
            dice_Result[7] = {};
            tmp_get = 0;

            bool two_two = false;
            int max = 0;
            int one_one_one_one = 0;          
        }
        cout << i << "\n";
    }

    cout << max_get;

    return 0;
}

4를 누르고 3 3 3 3 한줄만 넣어도 동작한다.
나머지 값이 들어가질 않아서 생기는 문제같다..
왜지?


가장 처음의 N으로 몇명인지 받고, 4로 받았고,
N명의 사람마다, 4번의 roll값을 입력 받도록 반복을 하는데,
처음 사람의 roll만 받고,
다음 2번째 사람의 roll을 받을 새도 없이 그냥 프로그램을 실행해버린다.

N명의 for문이 끝난 것도 아닌데,
왜 for문 내부의 roll for문이 실행이 안되고 바로 넘어갈까?

아 roll을 0으로 초기화를 하지 않았다.

시도 2

값이 이상하게 나와서 다음과 같이 조건내부에 cout문을 넣었다.

잘못되고 있는 것은, 3,4 번의 case이다.

dice_result값을 보니, 초기화가 제대로 안된듯 하다.

왜 안될까?
fill_n(dice_Result, 7, 0); 을 하니 정상적으로 동작한다.

하지만, 반례가 존재하는지 틀렸다고 뜬다.

해결

해당 조건을 만족하지 못하였다.
수정한다.

먼저 2개가 나온 경우, else로 가게 되는데,
여기서 2개짜리가 하나 나왔을 경우를 상정하고, 조건 4의 계산식을 사용한다.
그 후에, 2개가 또 나온 경우, two_two조건을 들어가게 되고,
이전 2개짜리 값을 상금을 역으로 계산하여 구하고, 조건 3의 계산식을 사용한다.

#include <iostream>
using namespace std;

int main()
{
    // ios::sync_with_stdio(0);
    cin.tie(0);

    int N;
    int one_roll;
    int dice_Result[7] = {};
    int count;

    // 예외상황들에 대한 변수
    bool two_two = false;
    int one_one_one_one = 0;
    int max = 0;

    cin >> N;
    int tmp_get = 0;
    int max_get = 0;

    // N명의 사람들마다
    for (int i = 0; i < N; i++)
    {
        // 4개의 주사위를 던진다.
        for (int roll = 0; roll < 4; roll++)
        {
            // scanf("%d", &one_roll);
            cin >> one_roll;
            dice_Result[one_roll]++;
            // cout << "roll : " << roll << "num :" << one_roll << "\n";
        }
        // 1~6의 숫자가 몇개씩 나왔는지 판단하여, 상금을 부여한다.
        for (int num = 1; num <= 6; num++)
        {
            if (dice_Result[num] >= 1)
            {
                if (dice_Result[num] >= 2)
                {
                    if (dice_Result[num] >= 3)
                    {
                        if (dice_Result[num] == 4)
                        {
                            tmp_get += 50000 + num * 5000;
                            //cout << "4개짜리 \n";
                        }
                        else
                        {
                            tmp_get += 10000 + num * 1000;
                            //cout << "3개짜리 \n";
                        }
                    }
                    else
                    {
                        if (two_two == true)
                        {
                            int x = (tmp_get - 1000) / 100; //x를 유추
                            tmp_get = 0;
                            tmp_get += 2000 + num * 500 + x * 500;
                        }
                        else
                        {
                            tmp_get += 1000 + num * 100;
                            two_two = true;
                        }
                    }
                }
                else
                {
                    one_one_one_one++;

                    if (max < num)
                    {
                        max = num;
                    }
                    if (one_one_one_one == 4)
                    {
                        //cout << "1개짜리 싹다\n";
                        tmp_get = max * 100;
                    }
                }
            }
            if (max_get < tmp_get)
            {
                max_get = tmp_get;
            }
        }
        //cout << i << " : " << tmp_get << "\n";

        // 변수 초기화
        //dice_Result[7] = {};

        fill_n(dice_Result, 7, 0);
        tmp_get = 0;

        two_two = false;
        one_one_one_one = 0;
        max = 0;
    }

    cout << max_get;

    return 0;
}

풀이

조건이 상당히 까다로웠는데,
문제를 적당히 읽고 모든 경우의 수를 생각하지 않았던 것이 1차적인 못푼 이유이고,
2차적으로는, CPP의 배열 초기화 dice_Result[7] = {}; <<이게 왜 초기화가 되지 않는건지 의문이지만,
fill_n이라는 함수를 통해서 초기화를 시킬 수 있었다.

6. 2309 - 브루트포스, 버블정렬

시도

#include <iostream>
using namespace std;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int height[9] = {};
    int sum = 0;
    int bubble_tmp;

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

    // 9명 키의 전체합
    for (int num : height)
    {
        sum += num;
    }

    for (int first = 0; first < 9; first++)
    {
        for (int second = first+1; second < 9; second++)
        {
            if ((sum - (height[first] + height[second])) == 100)
            {
                cout << "first : " << height[first] << "  second :" << height[second] << "\n\n\n\n\n" ;
                height[first] = 100;
                height[second] = 100;
                break;
            }
        }
        break;
    }

    for (int a = 0; a < 9; a++)
    {
        for (int b = 0; b < 9 - a - 1; b++)
        {
            if (height[b] > height[b + 1])
            {
                bubble_tmp = height[b + 1];
                height[b + 1] = height[b];
                height[b] = bubble_tmp;
            }
        }
    }

    for (int k = 0; k < 7; k++)
    {
        cout << height[k] << "\n";
    }

    return 0;
}

이 중에서, 아래 부분이 동작하지 않는다.

sum에서 - 했을시 100이 되는 first와 second를 찾지 못한다.
입력값과 sort는 문제 없는 것을 보아,
알고리즘에 문제가 있는 듯 한데...
판별하는 if문은 절대 틀릴수가 없고...
남은건 for문의 범위인데...

break가 문제였다. for문 이후 break..

해결

그래도 되지는 않았다. - 반례

#include <iostream>
using namespace std;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int height[9] = {};
    int sum = 0;
    int bubble_tmp;

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

    // 9명 키의 전체합
    for (int num : height)
    {
        sum += num;
    }

    for (int first = 0; first < 9; first++)
    {
        for (int second = first+1; second < 9; second++)
        {
            if ((sum - (height[first] + height[second])) == 100)
            {
                //cout << "first : " << height[first] << "  second :" << height[second] << "\n\n\n\n\n" ;
                height[first] = 100;
                height[second] = 100;
                break;
            }
        }
        //해당 구문이 핵심
        //위의 if문을 보면 break를 하면 해당 for문만 빠져나오게 되므로
        //아래처럼 수정해야 정상적으로 정답을 가지고 빠져나올 수 있다.
        if(height[first] == 100){
            break;
        }
    }

    for (int a = 0; a < 9; a++)
    {
        for (int b = 0; b < 9 - a - 1; b++)
        {
            if (height[b] > height[b + 1])
            {
                bubble_tmp = height[b + 1];
                height[b + 1] = height[b];
                height[b] = bubble_tmp;
            }
        }
    }

	//의미없이 큰 값을 가지게한 2개의 값을 제외하고, 7개만 보이게 된다.
    for (int k = 0; k < 7; k++)
    {
        cout << height[k] << "\n";
    }

    return 0;
}

풀이

해당 문제는 브루트포스와 버블정렬이 기름층처럼 층이 나눠진 문제였는데,
브루트포스와 버블정렬은 구현은 간단했으나, 브루트포스의 세부 조건이 문제였다.
브루트포스의 원리가, 다중 for문을 돌려서 무식하게 찾는 방식인데,
찾게 되는 경우에 어떻게 빠져 나올 것인가도 중요하게 작용한 듯 하다.


버블 정렬같은 경우는, 그냥 외워도 좋을 것 같지만,
간단하게 원리를 말하자면, 전체 원소 개수만큼 반복하는데,
그 이유는, 한 번 반복할 때마다. 가장 마지막 원소의 자리가 확정되기 때문이다.
그 값은 가장 큰 값이다.

그리고, 내부반복은 전체원소 - 현재 반복횟수 - 1인데,
a라는 반복횟수만큼 뒤에서 a번째까지 큰 값들이 자리를 잡았을 것이고,
그렇기 때문에 마지막 인덱스까지 확인할 필요없이 9-a 인덱스까지 보면 될 것이다.
하지만 -1까지 하는 이유는,
버블정렬의 알고리즘상 b로부터 b+1을 비교하기 때문에
알고리즘에 맞게 하려고 -1을 붙인다.

profile
Time Waits for No One

0개의 댓글