알고리즘/Algorithm

[기초] 1 - 2. 알고리즘을 시작하기 전에

** C / C++17, Java, Python 언어를 기반으로 진행했으며

모든 문제는 BOJ에서 풀어보실 수 있습니다.**

 

모든 코드는 불펌을 금지하며 학습을 목적으로 글을 작성하였습니다.

코드 작성자 : 본인 (백준 ID: happiness96)


알고리즘을 시작하기 전에


알고리즘을 시작하기 위해서는 먼저 프로그래밍 언어에 대한 기초 지식이 필요하다고 하였다.

자신이 프로그래밍 언어에 대한 기초 바탕이 돼있는지 확인하기 위해 간단히 몇 문제를 풀어볼 것이다.

 

앞서 조건문과 반복문을 잘 이해하고 있는지 테스트해보는 문제를 풀어보았다.

그렇다면 이번에는 무엇일까? 아마 PS를 하면서 런타임 에러를 가장 많이 발생시키는 녀석이 바로 이 녀석일 것이다.

 

손 풀기 정도로 생각하고 아직 이 정도도 어렵거나 벅차다면 프로그래밍 언어를 더 공부해야 할 때이다.


문제 목록


  1. [2562번] 최댓값
  2. [4344번] 평균은 넘겠지
  3. [15596번] 정수 N개의 합
  4. [1157번] 단어 공부
  5. [1032번] 명령 프롬프트


1. [2562번] 최댓값


☞힌트

더보기

배열을 사용해도 되지만 보통은 입력을 받으면서 처리를 해줘도 되는 문제다.

딱히 힌트랄 게 없다.. 이 문제를 틀린다면 구현력의 문제이므로 비슷한 문제를 많이 풀어보도록 하자.

만약 배열을 사용했다면 0 인덱스부터 잘 넣어줬는지 값을 출력하면서 확인해보자.

 


☞Solution

  • C언어
더보기
#include <stdio.h>

int main(){
    int numbers[9], result = 0, result_ind;

    for (int i = 0; i < 9; i ++) scanf("%d", &numbers[i]);

    for(int i = 0; i < 9; i ++){
        if (numbers[i] > result){
            result = numbers[i];
            result_ind = i + 1;
        }
    }

    printf("%d\n", result);
    printf("%d", result_ind);
    return 0;
}
  • C++
더보기
#include <iostream>
using namespace std;

int main(){
    int result = 0, result_ind;

    for (int ind = 1; ind < 10; ind ++){
        int number;

        cin >> number;

        if (number > result){
            result = number;
            result_ind = ind;
        }
    }

    cout << result << '\n' << result_ind;
    
    return 0;
}
  • Java
더보기
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int result = 0, result_ind = 0;

        for (int ind = 1; ind < 10; ind ++){
            int number = sc.nextInt();

            if (number > result){
                result = number;
                result_ind = ind;
            }
        }
        
        System.out.println(result);
        System.out.println(result_ind);

        sc.close();
    }
}
  • Python3
더보기
numbers = []

for _ in range(9):
    numbers.append(int(input()))

result = max(numbers)
print(result)
print(numbers.index(result) + 1)

 


2. [4344번] 평균은 넘겠지


☞힌트

더보기

문제를 잘 읽어봐야한다. 평균을 넘는 사람의 비율을 구하는 것이다.

배열을 활용하는 문제인데 뭔가 답이 잘 안나오는 것 같으면 팁을 한번 확인해보자.

혹은 디버깅을 통해 평균이 넘는 사람의 명수를 잘 세어줬는지도 체크해보자.

☞팁

더보기

혹시나 정수형을 실수형으로 형 변환하는걸 잘 모르겠다고 한다면 캐스트 연산자에 대해 알아보도록 하자.


☞Solution

  • C언어
더보기
#include <stdio.h>

int main(){
    int C;
    scanf("%d", &C);

    for (int i = 0; i < C; i ++){
        int N;
        scanf("%d", &N);

        int scores[N], total = 0;

        for (int i = 0; i < N; i ++){
            scanf("%d", &scores[i]);
            total += scores[i];
        }

        double avg = total / N;
        int over_avg = 0;

        for (int i = 0; i < N; i ++){
            if (scores[i] > avg) over_avg ++;
        }

        printf("%.3lf%%\n", (double)over_avg / N * 100);
    }

    return 0;
}
  • C++
더보기
#include <iostream>
#include <algorithm>
using namespace std;

int main(){
    int C;
    cin >> C;

    for (int i = 0; i < C; i ++){
        int N;
        cin >> N;

        int scores[N], total = 0;
        for (int j = 0; j < N; j ++){
            cin >> scores[j];
            total += scores[j];
        }

        double avg = total / N;
        int over_avg = 0;

        for (auto score: scores){
            if (score > avg) over_avg ++;
        }

        printf("%.3f%%\n", (double)over_avg / N * 100);
    }
    
    return 0;
}
  • Java
더보기
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int C = sc.nextInt();

        for (int i = 0; i < C; i ++){
            int N = sc.nextInt(), total = 0;
            int scores[] = new int[N];
            
            for (int j = 0; j < N; j ++){
                scores[j] = sc.nextInt();
                total += scores[j];
            }

            double avg = total / N;
            int over_avg = 0;

            for (int j = 0; j < N; j ++){
                if (scores[j] > avg) over_avg ++;
            }

            System.out.printf("%.3f%%\n", (double)over_avg / N * 100);
        }

        sc.close();
    }
}
  • Python3
더보기
C = int(input())

for _ in range(C):
    s = list(map(int, input().split()))
    N = s[0]

    total = 0

    for score in s[1:]: total += score

    average = total / N

    over_avg = 0

    for score in s[1:]:
        if score > average:
            over_avg += 1

    print("%.3f" % (over_avg / N * 100) + '%')

 


3. [15596번] 정수 N개의 합


☞힌트

더보기

백준에서 몇 안되는 함수 구현 문제이다.

이 문제를 잘 풀지 못하겠다면 아직 함수에 대한 이해가 부족하다고 할 수 있으므로 함수에 대해 더 공부해보도록 하자.

 

참고로 함수 명을 아무렇게나 해서 되는 게 아니라 문제에서 요구하는대로 따라줘야 한다.

☞Python 팁

더보기

문제에서 Python 파트를 보면 아마 생소한 표현들이 보일 것이다.

 

def solve(a: list) -> int:

 

알다시피 파이썬을 동적인 언어이다.

즉 변수 타입과 함수의 return 타입을 굳이 설정해주지 않아도 동적으로 타입을 지정해준다.

하지만 Python 3.5 ~ 3.6 버전부터 이런 정적인 표현도 가능하게끔 나왔다.

위 표현으로 예를 들어보자면 함수의 파라미터로 들어가는 a는 list이며 solve 함수의 return 타입은 int일 것이라고 명시를 해주는 것이다.

 

만약 solve 함수의 인자로 튜플을 주거나 함수 내부에서 return 해주는 타입을 문자열로 짰다면 에러를 발생시킬까?

그건 아니다. Warning으로 경고를 주기는 하지만 파이썬 언어 자체가 동적인 언어이기 때문에 이것으로 인한 에러를 발생시키지는 않는다.

 

현업이나 프로젝트에서 보다 이해하기 쉽도록 표시해주거나 타 언어 이용자들을 위한 일종의 약속 같은 거라고 보면 된다.

 

"나는 이 함수의 파라미터는 list 형태로 줄 것이고, 반환하는 값은 int형으로 해줄 거야."

"근데 왜 너 약속 안 지키고 tuple을 주는 거야!! 너 경고!"

☞Java 주의사항

더보기

클래스 이름이 Main이 아니라 Test임을 주의하자


☞Solution

  • C언어
더보기
long long sum(int *a, int n){
    long long ans = 0;

    for (int i = 0; i < n; i ++) ans += a[i];

    return ans;
}
  • C++
더보기
#include <vector>

long long sum(std::vector<int> &a){
    long long ans = 0;

    for (auto val: a){
        ans += val;
    }

    return ans;
}
  • Java
더보기
public class Test {
    long sum(int[] a){
        int n = a.length;
        long ans = 0;

        for (int i = 0; i < n; i ++) ans += a[i];

        return ans;
    }
}
  • Python3
더보기
def solve(a: list) -> int:
    ans = 0

    for val in a:
        ans += val

    return ans

 


4. [1157번] 단어 공부


☞힌트

더보기

문자열을 다뤄보는 문제다.

대문자와 소문자를 구별하지 않는다는 점을 주의하자. 즉, A와 a를 같은 문자로 본다는 것이다.

혹시나 아직 아스키코드를 모른다면 아스키코드에 대해 공부해보도록 하자.

 


☞Solution

  • C언어
더보기
#include <stdio.h>

int main(){
    char string[1000000];
    int counting[26];

    scanf("%s", &string);

    for (int i = 0; string[i] != '\0'; i ++){
        if (string[i] >= 'a') string[i] -= 32;

        counting[string[i] - 'A'] ++;
    }

    int max_count = 0;
    char res;

    for (int i = 0; i < 26; i ++){
        if (counting[i] > max_count){
            max_count = counting[i];
            res = i + 'A';
        }

        else if (counting[i] == max_count) res = '?';
    }

    printf("%c", res);

    return 0;
}
  • C++
더보기
#include <iostream>
using namespace std;

int main(){
    string s;
    int save[26] = {0,};

    cin >> s;
    
    for (auto ch: s){
        if (ch >= 'a') ch -= 32;

        save[ch - 'A'] ++;
    }

    int max_cnt = 0;
    char res;

    for (int i = 0; i < 26; i ++){
        if (save[i] > max_cnt){
            max_cnt = save[i];
            res = i + 'A';
        }

        else if (save[i] == max_cnt) res = '?';
    }

    cout << res;

    return 0;
}
  • Java
더보기
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String s = sc.nextLine();
        char res = '?';
        int length = s.length(), max_cnt = 0, counting[] = new int[26];

        s = s.toUpperCase();
        
        for (int ind = 0; ind < length; ind ++) counting[s.charAt(ind) - 'A'] ++;

        for (int i = 0; i < 26; i ++){
            if (counting[i] > max_cnt){
                max_cnt = counting[i];
                res = (char)(65 + i);
            }

            else if (counting[i] == max_cnt) res = '?';
        }

        System.out.println(res);
        
        sc.close();
    }
    
}
  • Python3
더보기
string = input().upper()

counting = {}

for ch in string:
    if ch not in counting:
        counting[ch] = 0
    
    counting[ch] += 1

max_val = 0
res = ''

for alpha, val in counting.items():
    if val > max_val:
        max_val = val
        res = alpha
    
    elif val == max_val:
        res = '?'

print(res)

 


5. [1032번] 명령 프롬프트


☞힌트

더보기

문자열을 처리하는 문제다.

Java와 Python의 문자열은 변경이 불가능함을 잊어서는 안 된다.

이 문제를 "틀렸습니다"를 받았다면 다른 여러 가지 반례를 넣어서 정답이 제대로 나오는지 확인해보자.

 


☞Solution

  • C언어
더보기
#include <stdio.h>

int main(){
    int N;
    char form[50];

    scanf("%d", &N);
    scanf("%s", &form);

    for (int i = 0; i < N - 1; i ++){
        char sub_s[50];

        scanf("%s", &sub_s);

        for (int ind = 0; sub_s[ind] != '\0'; ind ++){
            if (sub_s[ind] != form[ind]) form[ind] = '?';
        }
    }

    printf("%s", form);

    return 0;
}
  • C++
더보기
#include <iostream>
using namespace std;

int main(){
    string form;
    int N, length;

    cin >> N >> form;
    length = form.length();

    for (int i = 1; i < N; i ++){
        string str;
        cin >> str;

        for (int ind = 0; ind < length; ind ++){
            if (str[ind] != form[ind]) form[ind] = '?';
        }
    }

    cout << form;
    
    return 0;
}
  • Java
더보기
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int N, len;
        String form;

        N = sc.nextInt();
        sc.nextLine();
        form = sc.nextLine();
        
        len = form.length();

        for (int i = 1; i < N; i ++){
            String str;
            str = sc.nextLine();

            for (int ind = 0; ind < len; ind ++){
                if (str.charAt(ind) != form.charAt(ind)) form = form.substring(0, ind) + '?' + form.substring(ind + 1);
            }
        }

        System.out.println(form);
        sc.close();
    }
}
  • Python3
더보기
N = int(input())

form = list(input())

for _ in range(N - 1):
    file_name = input()

    for ind, val in enumerate(file_name):
        if val != form[ind]:
            form[ind] = '?'

print(''.join(form))