반응형


 

백준 - 단계별로 풀어보기 [1712]

https://www.acmicpc.net/problem/1712

 

 

문제

 

 

 

고정 비용 A와 노트북 한대를 생산하는데에 필요한 가변 비용 B 그리고 노트북 판매 가격 C를 입력받고, 손익분기점을 구하는 문제이다. 손익분기점이 발생하지 않는 경우에는 -1을 출력하면 된다.

 

풀이

 

단순히 해결 할 수 있는 문제이다. 오히려 반복문등을 활용한 풀이를 할 경우 시간초과가 발생할 수 있다.

결국 구해야하는 값은, 노트북 생산 단가 B와 판매 가격 C를 고려했을때 몇대를 팔아야 고정비용을 넘길 수 있느냐이기 때문에,

A / (C-B)에 1을 더한값이 구하고자 하는 값이다.

 

코드

 

#include <iostream>
using namespace std;
int main() {
    int a,b,c;
    cin >> a >> b >> c;
    int profit = 0;
    int cost = 0;
    if(c <= b)
    {
        cout << "-1";
        return 0;
    }
    cout << a/(c-b) + 1;
    return 0;
}

 

평가

 

수식을 활용하지 않고, 다른 방법으로 풀이하게 될 경우 시간 초과가 발생하도록 설계된 문제이다.

문제를 단순히 Brute Force방식으로 해결하려고 하지 말고, 최대한 규칙과 점화식을 찾아 낸 후 단번에 계산하는 방법을 알아 내야 한다.

 

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

백준 - 단계별로 풀어보기 [1316] 그룹 단어 체커

https://www.acmicpc.net/problem/1316

 

 

문제

 

 

임의의 문자열을 입력받은후, 알파벳의 연속 유무를 따져 그룹 단어인지 아닌지를 판별하는 프로그램을 작성하는 문제이다.

 

 

풀이

 

이전 문제와 비슷한 접근방법으로 풀 수 있는데, 각 알파벳에 대한 인덱스 배열을 만들고, 이전에 한번 나왔던 알파벳이 뒤에서 또 나오면 false를 반환하게끔하여 해결할 수 있다.

 

코드

 

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main() {
    int num;
    cin >> num;
    string *str;
    str = new string[num];
    int idx[26] = {0,};
    bool status = true;
    int count = 0;
    for(int i = 0; i < num; i++)
    {
        cin >> str[i];
    }
    for(int i = 0; i < num; i++)
    {
        status = true;
        memset(idx,0,sizeof(idx));
        for(int j = 0; j < str[i].length(); j++)
        {
            if(idx[str[i][j]-'a'] != 0)
                if(str[i][j-1] != str[i][j])
                {
                    status = false;
                    break;
                }
            idx[str[i][j]-'a']++;
        }
        if(status)
            count++;
    }
    cout <<count;
}

 

평가

 

정답률 51%로 그다지 어려운 문제는 아니다. 모든 값이 소문자로 주어진다는 조건이 있었기 때문에,
str[i][j] - 'a'와 같은 트릭이 통하는 문제이다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

백준 - 단계별로 풀어보기 [2941]

https://www.acmicpc.net/problem/2941

 

 

 

문제

 

 

 

최대 100글자의 문자열을 입력받고, 크로아티아 알파벳에 해당하는 문자들은 문자 1개로 계산하여 총 알파벳의 갯수를 세는 프로그램을 작성하는 문제이다.

 

 

풀이

 

 

해당 문제는 단순 if문으로 풀기보다는 크로아티아 알파벳에 해당하는 문자열들을 벡터로 선언하고, 이와 일치하는 문자열들을 변환하는 방식으로 풀 수 있다.

 

vector<string> croatian = {"c=","c-","dz=","d-","lj","nj","s=","z="};

 

그리고 String의 find 함수를 활용하여 일치하는 문자열을 String의 replace를 활용하여 #으로 변경해준뒤, 문자열의 길이를 구하면 총 크로아티아 알파벳의 개수를 구할 수 있다.

 

    for(int i = 0; i < croatian.size(); i++)
    {
        while(1){
            idx = str.find(croatian[i]);
            if(idx == string::npos)
                break;
            str.replace(idx,croatian[i].length(),"#");
        }
    }

 

위의 코드를 실행하며 크로아티아 알파벳에 해당하는 문자열들을 find를 통해 검색하고, find의 결과값이 npos가 나올 때 까지, 즉 모든 문자열을 찾을 때까지 while문을 통해 문자열을 변경해준다.

즉, c=, c-, dz=, d-, ...등등에 해당하는 문자열을 만나면 이를 #으로 변경해준다.

 

예시로 주어진 ljes=njak의 경우엔 #e##ak로 변경되어 문자열의 길이는 6을 반환하게 된다.

 

코드

 

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
    vector<string> croatian = {"c=","c-","dz=","d-","lj","nj","s=","z="};
    int idx;
    string str;
    cin >> str;
    for(int i = 0; i < croatian.size(); i++)
    {
        while(1){
            idx = str.find(croatian[i]);
            if(idx == string::npos)
                break;
            str.replace(idx,croatian[i].length(),"#");
        }
    }
    cout << str.length();
}

 

 

평가

 

본 문제는 string의 내부함수인 find와 replace등을 활용할 수 있는가, 없는가에 따라서 난이도가 달라질 수 있다고 생각한다.

단순히 모든 문자열을 if문으로 처리하는 경우에는 풀이는 간단하지만 코드 길이가 매우 난잡하게 길어질 수 있으며, dz=과 z=을 구분하기 위해 별도의 예외처리가 필요하므로, find를 활용하여 치환하는 방식이 효율적인 풀이 방법이라고 생각한다.

 

본 문제에서는 string  내부함수 find와 replace의 사용법을 익힐 수 있다.

 

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

백준 - 단계별로 풀어보기 [1152] 단어의 개수

https://www.acmicpc.net/problem/1152

 

 

문제

 

 

 

영어 대소문자와 띄어쓰기로 이루어진 문자열을 입력받고, 문자열 안에 들어있는 단어의 수를 구하는 프로그램을 짜는 문제이다. 한 단어가 여러 번 등장하면 등장한 횟수만큼 모두 세어야 한다.

단어는 띄어쓰기로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열의 앞과 뒤에는 공백이 있을 수도 있다.

 

풀이

 

문제의 조건에서 볼 수 있듯이, 공백을 포함한 문자열을 받아야하기 때문에, cin 함수보다는 getline 함수를 활용하여 문자열을 입력받아야한다.

 

#include <string>
...
string str;
getline(cin, str);

 

string을 받아오는 getline함수는 string 헤더파일에 들어있으며, 위의 경우 getline함수를 통해 표준 입력 cin을 str에 저장하라는 의미이다.

이를 통해 공백을 포함한 문자열을 입력 받을 수 있다.

 

따라서, 입력받은 문자열을 탐색하면서 공백이 있을 경우 단어의 카운팅을 늘려주면 된다.

단, 문자열에 연속된 공백은 없고, 문자열 앞과 뒤에는 공백이 있을 수 있다고 문제에 제시되어있으므로, 문자열의 맨 앞과 맨 뒤가 공백일 경우엔 새로운 단어가 아니므로 카운트를 1씩 줄여주면 해결되는 문제이다.

 

코드

 

#include <iostream>
#include <string>
using namespace std;
int main() {
    string str;
    getline(cin,str);
    int count = 0;
    bool space = false;
    if(str.empty())
    {
        cout << "0";
        return 0;
    }
    count = 1;
    for(int i = 0; i < str.length(); i++)
    {
        if(str[i] == ' ')
            count++;
    }
    if(str[0] == ' ')
        count--;
    if(str[str.length()-1] == ' ')
        count--;

    cout << count;
    return 0;
}

 

평가

 

공백을 포함한 문자열을 받는 방법에 익숙하지 않은 사람이 많아 정답률 25.565%라는 낮은 수치가 나오지 않았을까싶다.

C++에서 공백을 포함한 문자열을 받는 방법에 대해서 배울 수 있는 문제여서 포스팅을 진행하였다.

이번 문제에서는 getline함수의 사용법을 익히는 것에 중점을 두는 것이 좋을 듯 하다.

 

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

백준 - 단계별로 풀어보기 [1018] 체스판 다시 칠하기

https://www.acmicpc.net/problem/1018 

 

문제

 

M*N 크기의 보드를 잘라 8x8크기의 체스판을 얻으려고 하는데, 주어진 보드에서 8x8 체스판을 만들때, 가장 적게 색칠하는 횟수를 구하는 문제이다. 

입력으로는 N과 M, 행과 열 사이즈를 입력하고 보드가 어떻게 생겼는지를 B(Black)와 W(White)로 구분하여 입력한다.

 

 

풀이

 

해당 문제는 Brute Force 방식으로 해결하면 되는 문제이다. 모든 경우의 수를 모두 계산해본 후, 가장 재색칠이 적었던 경우를 출력해주면 된다. 체스판의 형태는 항상 2가지 형태로 고정되어있는데, 한가지는 검정색으로 시작하는 경우와 흰색으로 시작하는 경우이다.

이를 미리 string 배열로 만들어준다.

 

string WB[8] = {
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW"
};
string BW[8] = {
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB"
};

 

결국 재색칠해야하는 횟수는 저 두가지의 체스판과 다른 색깔의 총합을 구하면 알 수 있는것이다.

이때 절대 간과해서는 안되는것이, WB, BW를 모두 고려해야한다는것이다. 이 문제의 오답률이 높은 이유는 대부분의 사람들이 주어진 필드가 검은색으로 시작했다면 BW로 생긴 체스판과 비교를 하며 최소값을 찾으려고 하는데, 사실 제일 처음 필드를 W로 재색칠하고 시작하는 경우가 더 최소값일 수 있다.

 

그래서 시작이 검정색일 경우와, 흰색일 경우를 각각 고려해서 함수를 짜서 문제를 해결하였다.

 

int WB_cnt(int x, int y)
{
    int cnt = 0;
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            if(board[x+i][y+j] != WB[i][j])
                cnt++;
        }

    }
    return cnt;
}

int BW_cnt(int x, int y)
{
    int cnt = 0;
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            if(board[x+i][y+j] != BW[i][j])
                cnt++;
        }

    }
    return cnt;
}

 

배열의 좌표 x,y를 받아온 후, 해당 위치를 첫 필드로 가지는 체스판이 검정색으로 먼저 시작할 경우 몇 번의 수정이 필요한지를 구하는지를 구하는 BW_cnt함수와 흰색으로 먼저 시작할 경우 몇 번의 수정이 필요한지를 구하는 WB_cnt 함수를 선언하였다.

 

그 후, 입력받은 보드의 크기를 고려하여, 8x8의 체스판을 생성할 수 있는 범위를 정하여, BW_cnt와 WB_cnt함수를 호출하고, 이중에 더 작은 값을 찾아가며 for문을 호출한다.

 

    for(int i = 0; i + 8 <= N; i++)
    {
        for(int j = 0; j + 8 <= M; j++)
        {
            int tmp;
            tmp = min(WB_cnt(i,j),BW_cnt(i,j));
            if(tmp < min_val) {
                min_val = tmp;
            }
        }
    }

 

위와 같은 호출을 통해, 만들 수 있는 모든 체스판과 재색칠이 필요한 횟수를 구할 수 있다.

그리고 최종적으로 제일 작았던 값이 저장된 min_val을 출력시켜주면 해당 문제를 해결할 수 있다.

 

코드

 

#include <iostream>
#include <string>
#include <algorithm>
#include <utility>
using namespace std;
string WB[8] = {
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW"
};
string BW[8] = {
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB",
        "BWBWBWBW",
        "WBWBWBWB"
};
string board[50];
int WB_cnt(int x, int y)
{
    int cnt = 0;
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            if(board[x+i][y+j] != WB[i][j])
                cnt++;
        }

    }
    return cnt;
}
int BW_cnt(int x, int y)
{
    int cnt = 0;
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            if(board[x+i][y+j] != BW[i][j])
                cnt++;
        }

    }
    return cnt;
}
int main() {
    int size[2];
    int cnt;
    int min_val = 12345;
    pair<int, int> p1;
    cin >> p1.first >> p1.second;
    for(int i = 0; i < p1.first; i++)
        cin >> board[i];
    for(int i = 0; i + 8 <= p1.first; i++)
    {
        for(int j = 0; j + 8 <= p1.second; j++)
        {
            int tmp;
            tmp = min(WB_cnt(i,j),BW_cnt(i,j));
            if(tmp < min_val) {
                min_val = tmp;
            }
        }
    }
    cout << min_val;
    return 0;
}

 

 

 

평가

 

좌표계나 행렬 인덱스를 저장하기 좋은 pair라는 STL 자료형을 사용하며 공부할 수 있었던 문제이다.

또한 Brute Force 알고리즘의 대표적인 예시로, Brute Force는 이런 방식으로 풀이하면 된다는 느낌으로 포스팅을 진행하였다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


백준 - 단계별로 풀어보기 [1157] 단어 공부

https://www.acmicpc.net/problem/1157 

 

 

문제

 

 

알파벳 대소문자로 이루어진 단어가 입력되면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하는 문제이다.

핵심은 대문자와 소문자를 구분하지 않는것이다.

출력은 가장 많이 사용된 알파벳을 대문자로 출력하는것이고, 만약 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.

 

 

풀이

 

이 문제의 경우에는 입력받은 문자열을 모두 대문자로 변경하고 풀이하는것이 여러모로 용이하다.

그렇기 때문에 STL의 transform 함수등을 사용하여 문자열 전체를 대문자로 바꾼 뒤, 배열 인덱스를 이용하여 각 알파벳이 몇번 사용되었는지 저장하는 접근 방식으로 해당 문제를 해결할 수 있다.

 

#include <algorithm>

int main() {
	string c;
	cin >> c;
	transform(c.begin(), c.end(), c.begin(), (int(*)(int))toupper);
	return 0;
}

 

위의 사용법은, c 문자열 전체를 대문자로 변환하여 다시 c에 저장하라는 의미를 담고 있다.

이 코드를 실행하여 먼저 문자열을 모두 대문자로 변환하고, 그 후 배열을 선언하여 각 알파벳이 몇 번 사용되었는지를 계산한다.

 

 * 윈도우의 경우 toupper만 입력해도 정상적으로 작동되지만, 리눅스, 맥의 기본 컴파일러에서는 toupper만 입력시 자료형이 ambiguous 하여 에러가 발생한다. 따라서 맥이나 리눅스 유저는 (int(*)(int))로 확실히 자료형 캐스팅을 진행하여야한다.

 

코드는 다음과 같다.

 

int a[26] = {0,};
transform(c.begin(), c.end(), c.begin(), (int(*)(int))toupper);
for(int i = 0; i < c.length(); i++) {
    a[c[i] - 'A']++;
}

 

위 코드가 의미하는바는 다음과 같다.

c[i]는 해당 문자열의 아스키코드를 의미하므로 c[i]가 A일경우, 'A' - 'A' = 0, B일경우, 'B' - 'A' = 1 로 처리되어 인덱스 순서대로 0부터 A, 25가 Z로 표현할 수 있다.

즉 해당 알파벳이 몇번 등장했는지 계산할 수 있는 코드이다.

 

그 후 가장 큰 값을 찾아 출력을 해주면 정상적으로 풀이가 가능하다.

 

코드

 

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
    string c;
    cin >> c;
    int max = 0;
    int cnt = 0;
    int target;
    int a[26] = {0,};
    transform(c.begin(), c.end(), c.begin(), (int(*)(int))toupper);
    for(int i = 0; i < c.length(); i++)
    {
        a[c[i] - 'A']++;
    }

    for(int i = 0; i < 26; i++)
    {
        if(max < a[i])
        {
            max = a[i];
            cnt = 0;
            target = i;
        }
        if(max == a[i])
            cnt++;
    }
    if(cnt > 1)
        cout << "?";
    else
        cout << (char)(target+'A');
    return 0;
}

 

출력을 위해서는 가장 빈도가 높았던 문자의 인덱스값에다가 아까 빼주었던 'A' 를 더해주면 다시 아스키값으로 변환된다.

이때 출력형을 char형으로 캐스팅해주지 않으면 문자의 아스키값이 나오고 문자가 나오지 않으므로 char형으로 형변환을 반드시 해주어야 한다.

평가

 

STL을 활용하여 대문자로 변환을 하면 아주 편해지는 문제이다.

STL을 활용하지 못했을 경우, if문을 사용해서 'a' << x << 'z' 과 'A' << x << 'Z' 식의 구문을 작성해야하는데, 프로그래밍 효율이 떨어진다.

transport 함수를 활용하여 대문자, 소문자로 변경하는 방법은 알아두면 문자열처리에 아주 유용할 것 같아서 정리한 포스팅이다.

정답률은 38%로 꽤 낮은 편이다.

 

본 문제에서는 transport의 활용과 ASCII 코드 값을 활용한 트릭에 대해서 짚고 넘어가면 좋을 것 같다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


백준 - 단계별로 풀어보기 [10809] 알파벳 찾기 

https://www.acmicpc.net/problem/10809 

 

 

 

문제

 

 

알파벳 소문자로만 이루어진 단어를 입력받고, a~z 각각의 알파벳에 대해서 처음 등장하는 위치를, 포함되어 있지 않은 경우에는 -1을 출력하는 프로그램을 작성하는 문제이다.

 

 

풀이

 

char 배열을 활용하여 문제를 풀어도 되겠지만, C++에서 제공하는 string STL을 활용하면 아주 간단하게 풀 수 있는 문제이다.

string STL의 find 함수는 입력 문자열이 최초로 등장하는 위치의 인덱스를 반환하는 함수이다. 즉 위 문제의 경우 'a' 'b' 'c' ... 등등에 대한 find만 수행해주면 된다는 의미이다.

사용법은 아래와 같다.

 

#include <iostream>
#include <string>
using namespace std;


int main() {
	string a = "abc";
	cout << a.find('a') << '\n'; 
	cout << a.find('b') << '\n'; 
	cout << a.find('c') << '\n';
	cout << a.find('d') << '\n';
	return 0;
}

/* 
실행 결과
0
1
2
18446744073709551615 (unsigned형의 -1이므로 표현할 수 있는 최대 크기의 양수)
*/

 

만약 없는 문자열을 찾으려 할 경우에는 string::npos가 반환된다.

npos의 값은 -1로 정의되어있지만, string::npos의 자료형이 unsigned이므로 2의 보수 개념에 의해 표현할 수 있는 최대 크기의 양수가 출력된다. 이를 방지하기 위해서는 unsigned가 아닌 일반 int형으로 캐스팅을 진행하여 출력하면 된다.

 

cout << (int)a.find('d') << '\n';

 

이렇게 출력할 경우 정상적으로 -1을 받아오는 것을 확인할 수 있다.

 

코드

 

#include <iostream>
#include <string>
using namespace std;
int main() {
    string s;
    string alphabet = "abcdefghijklmnopqrstuvwxyz";
    cin >> s;
    for(int i = 0; i < alphabet.length(); i++)
        cout << (int)s.find(alphabet[i]) << " ";
    return 0;
}

 

 

평가

 

C++이 편리한 이유중 하나인 string을 활용할 수 있다면 보다 쉽게 풀 수 있는 문제였다.

문제 난이도 자체는 높지 않지만, string의 멤버 함수인 find를 연습할 수 있다는 점에서 포스팅을 진행하였다.

정답률은 50%이상으로 평이하지만, STL을 사용했는가 안했는가에 따라서 코드 길이 차이와 푸는 시간 차이가 클 것이라고 생각한다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


백준 - 단계별로 풀어보기 [4344] 평균은 넘겠지

https://www.acmicpc.net/problem/4344 

 

 

문제

 

 

대학생들의 점수를 입력 받은 후, 평균을 넘는 학생들의 비율을 구하는 문제이다.

입력은 테스트 케이스의 개수 C와 학생들의 수, 학생들의 점수가 주어진다. 

각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다.

 

 

풀이

 

이차원 배열의 동적 할당과 반복문을 활용하여 풀 수 있는 문제이다.

문제 자체가 정말 다양한 풀이법이 나올 수 있고, 굳이 이차원 배열이 아니고 다른 방법으로 푸는 방법도 있을 것이라고 생각된다.

먼저 테스트 케이스의 개수 C를 입력받은후, C개 만큼의 이차원배열 행을 동적할당한다.

 

int c;
scanf("%d",&c);
int **array = new int*[count];
float *means = new float[count]; //평균은 소수이므로 float자료형

 

그 후 학생의 수는 최대 1000명이라고 했으므로, 열 1000개와 학생 수 1에 해당하는 1001개의 동적할당을 진행해준다.

 

for (int i = 0; i < count; i++)
{
    array[i] = new int[1001];
}

 

그 후엔, 학생들의 수를 입력받고, 해당하는 수 만큼의 점수를 입력받는다. 

그 후 점수의 합을 통해 평균을 구하고, 평균을 넘은 학생들의 수를 세어 비율을 구하면 되는 문제이다.

이 때 소수 셋째자리에서 반올림을 하여 표현하라고 하였으므로,

%.3f 의 형식지정자를 사용하여 출력하면 원하는 출력값을 얻을 수 있다.

 

코드

 

#include <cstdio>
int main() {
    int count;
    scanf("%d",&count);
    int **array = new int*[count];
    float *means = new float[count];
    int sum = 0;
    int goodstudent = 0;
    for (int i = 0; i < count; i++)
    {
        array[i] = new int[1001];
    }
    for (int i = 0; i < count; i++)
    {
        sum = 0;
        scanf("%d",&array[i][0]);
        for (int j = 1; j <= array[i][0]; j++)
        {
            scanf("%d",&array[i][j]);
            sum += array[i][j];
        }
        means[i] = (float)sum / array[i][0];
        for (int j = 1; j <=array[i][0]; j++)
        {
            if(array[i][j] > means[i])
            {
                goodstudent++;
            }
        }
        printf("%.3f%%\n",(float)goodstudent/array[i][0] * 100);
        goodstudent = 0;
    }
    return 0;
}

 

 

평가

 

이차원 배열 활용을 묻는 문제라고 생각된다.

배열의 첫 인자값이 점수가 아니고 학생의 수를 받아오기 때문에 반복문이 조금 복잡해질수는 있다. 필자의 코드도 완전 효율적인 코드는 아닐 수 있다고 생각한다. 이번 문제의 정답률은 38.361%로 매우 낮은편인데, 개인적으로는 왜 저렇게까지 낮은지는 이해가 되지 않는 문제였다. 본 문제에서는 이차원 배열과 동적할당에 대해서 알아두고 가면 좋을 것 같다고 생각한다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


백준 - 단계별로 풀어보기 [10951] A+B - 4

https://www.acmicpc.net/problem/10951 

 

 

문제

 

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

입력은 여러 개의 테스트 케이스로 이루어져 있다.

각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)

각 테스트 케이스마다 A+B를 출력한다.

풀이

 

해당 문제는 입력을 마치는 조건이 없기 때문에, EOF 개념을 활용하여 풀어야 하는 문제이다.

EOF란 End Of File의 약자로, ASCII코드 값 -1을 가진다. 일반적으로 파일의 마지막을 만났을 때 EOF 값을 가져오지만, 입력을 직접 받아올 수도 있다. Ctrl+Z를 입력할경우 EOF 값인 -1이 getchar나 scanf를 통해 들어간다.

 

해당 문제는 개인적으로, EOF 조건에 대한 부연설명이 미흡했다고 생각한다. 

입력의 개수가 주어지지 않는 경우, 일반적으로 EOF를 활용하여 처리를 한다고 한다.

EOF를 체크하는 방법은 간단하다.

while(scanf("%d %d", &a, &b) != EOF){...}

위와 같은 반복문 처리를 해주면 EOF까지만 입력을 받을 수 있다.

 

 

코드

 

#include <cstdio>

int main() {
    int a[1000];
    int b[1000];
    int i = 0;
    while(scanf("%d %d",&a[i],&b[i]) != EOF)
    {
        i++;
    }

    for(int j = 0; j < i; j++)
    {
        printf("%d\n",a[j]+b[j]);
    }
    return 0;
}

 

 

 

평가

 

EOF 개념이 생소하다면 입력이 끝나는 조건을 어떻게 프로그램이 알게 할 것인지에 대해서 고민에 빠질 수 있는 문제이다.

이번 문제도 정답비율 38%로 유독 낮은 정답률을 가지고 있었다.

EOF를 활용한 입력 종료를 학습하는 용도로 보면 좋을 것 같다.

 

 

 

 

 

 

 

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형

 


백준 - 단계별로 풀어보기 [10172] 개

https://www.acmicpc.net/problem/10172

 

 

문제

 

아래 예제와 같이 개를 출력하시오.

 

|\_/|

|q p| /}

( 0 )"""\

|"^"` | |

|_/=\\__|

 

 

풀이

 

본 문제는 탈출 문자 개념을 아는가, 그리고 \, " 등의 문자들을 정상적으로 출력할 수 있는가를 물어보는 문제이다.

초보자들이 자주 할 수 있는 실수가 바로 탈출 문자를 고려하지 않는것이다.

예를 들어 printf(""Hello"");의 경우 Hello이전에 이미 따옴표가 2개가 나왔기 때문에 printf(" "Hello " " );로 인식되어 따옴표 뒤에 printf문을 닫는 괄호가 없다는 컴파일 에러를 발생시키게 된다. 

 

이처럼 \, " 는 탈출(Escape) 문자를 표현할 때 사용되기 때문에 컴파일러에게 혼동을 줄 수 있다.

따라서 printf 문의 " " 사이에 해당 문자들을 출력하려면 단순 출력용이라는것을 명시하기 위해 \를 추가하기로 약속되어있다.

아래의 표는 printf문에서 사용될 수 있는 다양한 탈출 문자열들이다. 아마 대부분의 사람들이 \n에는 상당히 익숙하겠지만, 다른 탈출 문자열들은 다소 생소하게 느껴질 것이다. (사실 그만큼 쓰임새가 없긴 하다.)

 

<탈출 문자>

 

위의 표에 따라서, 

\ -> \\

" -> \"

위와 같이 코드를 출력문을 작성하면 정상 출력이 가능하게 된다.

 

코드

 

#include <cstdio>

int main() {
	printf("|\\_/|\n");
	printf("|q p|   /}\n");
	printf("( 0 )\"\"\"\\\n");
	printf("|\"^\"`    |\n");
	printf("||_/=\\\\__|\n");
	return 0;
}

 

 

평가

전공자들에게는 C언어 과목을 배우면서 여러번 배웠을 내용이지만, 의외로 기초적인 내용을 잊어버리는 경우도 많은 것 같다.

전공자인 본인 또한 마찬가지로 문제를 보고 "아~ 이거 알지!" 해놓고 정작 풀이하는데는 굉장히 혼란스러웠었다.

 

실제로 해당문제의 정답비율은 38%로 매우 낮은 정답률을 기록하고 있다. 

대부분 풀 수 있지만 귀찮아서 넘어가는 경우가 많았을 것이지만, 그래도 기초부터 탄탄히 하자는 의미에서 포스팅을 진행하였다.

 

 

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,