본문 바로가기

5. 방학 활동/Write UP

[2022.07~08] 백준 알고리즘 문제 풀이 스터디

안녕하세요, 성신여대 해킹동아리 I.Sly()입니다. :)

이번 방학 동안은 Baekjoon Online Judge 문제를 해결하는 스터디를 진행했습니다.

 

이번 스터디는 본인이 원하는 난이도, 원하는 문제를 원하는 언어로 해결한 후, Notion에 코드를 업로드하는 방식으로 진행되었습니다.

그리고 매주 한 번씩 정기 스터디를 통해 한 주 동안 해결한 문제를 인증하고, 각자의 알고리즘을 피드백하는 시간을 가졌습니다.

 

스터디 기간 동안 각자 약 30문제 정도를 해결하였습니다.

이 문제들 중 몇 가지 문제 풀이 코드들을 공유해 드리며 일지 마치겠습니다. :)

 

[10825] 국영수

 

10825번: 국영수

첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 1

www.acmicpc.net

#include <iostream>
#include <string>
#include <algorithm>  // sort함수 사용을 위한 라이브러리 include
#include <vector>  // vector를 생성하면 메모리 heap에 생성되며 동적할당될 수 있어서 더 효율적임.
using namespace std;

struct Student {   // 학생의 국어, 영어, 수학 점수를 받는 자료구조
	string name;
	int kor, eng, math;
};
Student s[100001];

bool comp(Student &a, Student &b) {
/*
< 정렬 > 
1. 국어 점수가 감소하는 순서로
2. 국어 점수가 같으면 영어 점수가 증가하는 순서로
3. 국어 점수와 영어 점수가 같으면 수학 점수가 감소하는 순서로
4. 모든 점수가 같으면 이름이 사전 순으로 증가하는 순서로 (단, 아스키 코드에서 대문자는 소문자보다 작으므로 사전순으로 앞에 온다.)
*/
	if (a.kor == b.kor) {
		if (a.eng == b.eng) {
			if (a.math == b.math) 
				return a.name < b.name;
			else return a.math > b.math;
		}
		else return a.eng < b.eng;
	}
	return a.kor > b.kor;
}

int main(void) {
	ios_base::sync_with_stdio;  // 빠른 입출력으로 개선하기 위한 코드 3줄
  cin.tie(NULL);
  cout.tie(NULL);

	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {  // 학생의 이름, 국어, 영어, 수학 점수 입력받음
		cin >> s[i].name;
		cin >> s[i].kor;
		cin >> s[i].eng;
		cin >> s[i].math;
	}
	sort(s, s + n, comp);   // 정렬함수 호출

	for (int i = 0; i < n; i++) {
		cout << s[i].name << "\n";
	}

	return 0;
}

 

[10971] 외판원 순회 2

 

10971번: 외판원 순회 2

첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 10) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j

www.acmicpc.net

#include <stdio.h>

int map[13][13], a[11], min=2000000,N; // n개의 줄이므로 방문하는 노드 한정

int search(int x, int total, int v) // 탐색 함수
{
   if( x==1 && v==N+1){ // 시작 노드가 달라도 탐색 결과는 같기 때문에 바로 탐색 시작
      if(total<min) min=total;
      return 0;
   }
   if(a[x]) return 0;
   a[x]=1; // 방문한 노드는 1로 설정

   for (int i=1; i<=N; i++){
      if(map[x][i]){
         total+=map[x][i]; // 결과 값에 비용 추가
         search(i,total,v+1); // 재귀함수로 과정 진행
         total-=map[x][i]; // 다른 경로 탐색을 위해 결과값에 더한 직전 값을 뺀다
      }
   }
   a[x]=0; // 함수가 끝나면 다시 0으로 
   return min;
}

int main(){
   scanf("%d", &N);
            for(int i=1; i<=N; i++)
      for(int j=1; j<=N; j++)
         scanf("%d", &map[i][j]); // 노드 입력 받기
   printf("%d",search(1,0,1));
   return 0;
]

 

[1356] 유진수

 

1356번: 유진수

첫째 줄에 수 N이 주어진다. 이 수는 2,147,483,647보다 작거나 같은 자연수이다.

www.acmicpc.net

T = list(map(int, input()))
Ten = len(T)   #유진수란 어떤 수를 10진수로 표현한 뒤 그 수를 두 부분으로 나눴을 때 앞부분 자릿수의 곱과 뒷부분 자릿수의 곱이 같을 때를 말함
               # 먼저 입력받은 수를 한 자리 씩 리스트에 저장하는 방식으로 진행

if Ten == 1:   # Ten의 길이가 1이면 유진수가 아니므로 NO 출력
   print('No')
else :
   a = b = 1
   for i in range(Ten - 1): # 각 부분으로 나누기
       a = b = 1
       for j in range(i+1): # 나뉜 수의 앞부분 곱하기
           a *+= N[j]
       for q in range(i + 1, Ten): # 나뉜 수의 뒷부분 곱하기
           b *= N[q]
       if a == b: # 앞부분의 곱과 뒷부분의 곱을 비교하여 같다면 수 나누기를 중단하고 YES를 출력하고 나누기가 끝나도 같은 경우가 없다면 NO 출력
           break

  if a == b:
      print('YES')
  else:
      print('NO')

 

[3040] 백설 공주와 일곱 난쟁이

 

3040번: 백설 공주와 일곱 난쟁이

매일 매일 일곱 난쟁이는 광산으로 일을 하러 간다. 난쟁이가 일을 하는 동안 백설공주는 그들을 위해 저녁 식사를 준비한다. 백설공주는 의자 일곱개, 접시 일곱개, 나이프 일곱개를 준비한다.

www.acmicpc.net

#include <stdio.h>
 
int main() {
    int arr[9];
    int check[9] = { 0, };
    int sum = 0;
 
    //각 난쟁이의 숫자를 입력받고, 
    //총 합계를 구함.
    for (int i = 0; i < 9; i++) {
        scanf("%d", &arr[i]);
        sum += arr[i];
    }
 
    //총합에서 100만큼 빼주기
    sum -= 100;
 
    //두명의 합이 sum과 같은지 확인
    int find = 0;
    for (int i = 0; i < 8; i++) {
        for (int j = i + 1; j < 9; j++) {
            //찾으면 해당 인덱스를 표시하고 종료
            if (arr[i] + arr[j] == sum) {
                check[i] = check[j] = 1;
                find = 1;
                break;
            }
        }
        if (find) break;
    }
 
    //결과출력
    for (int i = 0; i < 9; i++) {
        if (!check[i]) printf("%d\n", arr[i]);
    }
 
    return 0;
}

 

[2445] 별 찍기 - 8

 

2445번: 별 찍기 - 8

첫째 줄부터 2×N-1번째 줄까지 차례대로 별을 출력한다.

www.acmicpc.net

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

int main() {
	int count;

	cin >> count;

	for (int i = 0; i < 2 * count - 1; i++) {
		for (int j = 0; j < abs(i - (count - 1)) * (-1) + count ; j++) {
			cout << "*";
		}

		for (int j = abs(2 * (i - (count - 1))); j > 0; j--) {
			cout << " ";
		}


		for (int j = 0; j < abs(i - (count - 1)) * (-1) + count; j++) {
			cout << "*";
		}

		cout << "\n";
	}


	return 0;
}