#include<iostream>#include<algorithm>usingnamespace std;
int num[1000];
intmain(){
int n;
cin >> n;
for (int i = 0; i < n; i++) cin >> num[i];
sort(num, num + n);
for (int i = 0; i < n; i++) cout << num[i] << '\n';
return0;
}
sort함수는 세 개의 인자를 받습니다. sort(배열의 시작, 배열의 끝, 정렬 방법) 이라고 생각하시면 편합니다. 세번째 인자를 생략하면 자동 오름차순으로 정렬됩니다.
좀 더 정확히 설명해봅시다.
int arr[5] = { 4, 3, 2, 1, 0 };
int형 원소들을 갖고 있는 arr배열을 오름차순으로 정렬하고싶다면,
sort(arr, arr + 5);
이 코드 한줄로 끝나게 됩니다.
한가지 의문이 듭니다. 왜 배열의 끝이 arr + 4가 아니라 arr + 5일까 ?
밑에 그림을 보겠습니다.
간단하쥬 ? 이 그림이 이해가 안가신다면 포인터 개념을 공부해주시면 됩니다.
이번엔 vector를 이용해봅시다.
vector<int> vec = { 4, 3, 2, 1, 0};
위에 배열과 같은 원소를 갖는 vector를 만들었습니다.
마찬가지로 오름차순으로 정렬하고 싶습니다.
sort(vec, vec + 5);
하면 에러입니다.
vector는 STL에서 제공하는 자료구조이기 때문에 iterator(반복자)를 인자로 넣어주어야 합니다.
sort(vec.begin(), vec.end());
이 옳은 방법입니다.
혹시 vector에서 모든 원소 정렬이 아닌 원하는 부분만 정렬하고 싶다면,
sort(vec.begin() + a, vec.begin() + b);
와 같은 방식으로 a부터 b - 1번째 원소들만 정렬할 수 있습니다.
이번엔 세번째 인자에 대해 알아봅시다.
sort함수가 수행될 때, 어떤 기준으로 정렬이 될 지 정해주는 부분입니다.정의하는 방법은 세 가지 정도 있지만, 가볍게 함수로 정의하는 방법만 보겠습니다.
#include<iostream>#include<vector>#include<algorithm>usingnamespace std;
boolcompare(int& a, int& b){
// (a보다 b가 더 크면 true, 아니면 false) == 오름차순return a < b;
}
int arr[5] = {4, 3, 2, 1, 0};
vector<int> vec = {4, 3, 2, 1, 0};
intmain(){
sort(arr, arr + 5, compare);
sort(vec.begin(), vec.end(), compare);
return0;
}
보시는 것처럼 간단합니다. 같은 자료형 두 개를 인자로 받고, bool값을 리턴해주는 함수를 작성해주면 비교함수 완성.
return a > b; 를 하면 당연하게도 내림차순으로 정렬됩니다.
살짝 tip 아닌 tip을 드리자면 STL에서 제공하는 functional 라이브러리 안에 less<자료형>()과 greater<자료형>() 함수가 있습니다. 매번 compare함수를 작성하는게 귀찮으신 분들은 이 두 함수를 이용하셔도 되지만, 단순한 내림차순 오름차순 정렬임을 유의해주셔야합니다.
: 힙 정렬(Heap Sort), 병합 정렬(Merge Sort), 퀵 정렬(Quick Sort)
정도는 스스로 구현할 줄 알아야 한다고 개인적으로 생각합니다.
하지만, 알고리즘 문제를 해결할 때마다 구현하는 것은 굉장한 시간 낭비일 것입니다. 따라서 저는 algorithm 라이브러리에서 제공하는 sort함수를 사용하여 12단계의 문제들을 해결할 예정입니다.
제가 올리는 글에선 sort함수 사용방법을 배우시고, 만약 위에 언급된 6개 정렬 중 모르는 것이 있다면 꼭 공부해보시는 것을 추천드립니다.
백준에서 제공하는 일반적인 알고리즘 문제에선 sort 함수로도 충분히 통과가 가능하지만, 삼성 B형 테스트와 같이 메모리와 시간 최적화가 필요한 문제들은 스스로 정렬 알고리즘을 구현할 줄 알아야 하기 때문입니다. 시간이 허락한다면, 저도 제가 구현한 코드를 사용하여 문제들을 해결해보도록 하겠습니다. 감사합니다.
맨 왼쪽 위칸이 검은색인 경우와 흰색인 경우의 (8x8)체스판을 미리 준비해놓고, NxM체스판 위를 돌아다니며 미리 준비해둔 8x8 체스판과 몇 칸이 다른지 확인해보자. 가장 적은 칸이 다른 경우가 답이 된다.
이 아이디어가 가능한지 시간 복잡도를 생각해보자.
최악의 경우로 (50x50)크기의 체스판에서 (42x42)개의 (8x8)체스판을 뽑아낼 수 있고, 체스판을 한번 뽑아낼 때마다 2x64번의 비교가 필요하다. 따라서 최대 42x42x2x64(=225,792)번의 연산만 하면 되기 때문에 브루트 포스가 가능하다.
#include<bits/stdc++.h>usingnamespace std;
typedeflonglong ll;
constint INF = 2147483647;
constint MAX = 10e+8;
ll gcd(ll a, ll b){ for (; b; a %= b, swap(a, b)); return a; }
char chess[50][50];
char b[50][50]; // 맨 왼쪽 위 칸이 black인 경우char w[50][50]; // 맨 왼쪽 위 칸이 white인 경우intmain(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
cin >> N >> M;
string s;
int ans = 987654321;
for (int i = 0; i < N; i++) {
cin >> s;
for (int j = 0; j < M; j++) {
chess[i][j] = s[j];
// 미리 b배열과 w배열 채워놓기if ((i + j) % 2 == 0) {
b[i][j] = 'B';
w[i][j] = 'W';
}
else {
b[i][j] = 'W';
w[i][j] = 'B';
}
}
}
// 8x8로 잘라서 비교 for (int i = 0; i < N - 7; i++) for (int j = 0; j < M - 7; j++) {
int tmpB = 0, tmpW = 0;
for (int x = i; x < i + 8; x++) for (int y = j; y < j + 8; y++) {
if (chess[x][y] != b[x][y]) tmpB++;
if (chess[x][y] != w[x][y]) tmpW++;
}
ans = min({ ans, tmpB, tmpW }); // min이 자주 수행되는 경우엔 2개씩 비교하는게 더 좋다.
}
cout << ans << '\n';
return0;
}
따라서 번의 연산이 필요하고, 이는 문제에서 주어진 2초 안의 충분히 해결할 수 있는 연산량이다. 때문에 브루트 포스로 해결하자 !
#include<bits/stdc++.h>usingnamespace std;
typedeflonglong ll;
constint INF = 2147483647;
constint MAX = 10e+8;
ll gcd(ll a, ll b){ for (; b; a %= b, swap(a, b)); return a; }
intmain(){
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, ans = 0;
cin >> n;
// 생성자는 n보다 작을 수 밖에 없다.for (int i = 1; i <= n; i++) {
int cur = i, sum = i;
// 분해합 구하기while (cur) {
sum += cur % 10;
cur /= 10;
}
// 가장 작은 생성자를 구해야하기 때문에 찾자마자 for문 종료if (sum == n) {
ans = i;
break;
}
}
cout << ans;
return0;
}
카드가 총 백장이므로 완전 탐색을 진행하여도 개의 경우의 수 밖에 안나온다. 따라서 완탐으로 진행하자.완전 탐색하는 방법은 재귀 함수를 이용하면 되는데, 3개만 뽑으면 되기 때문에 3중 for문도 가능할 것으로 보인다.
1. 재귀 함수
#include<bits/stdc++.h>usingnamespace std;
typedeflonglong ll;
constint INF = 2147483647;
constint MAX = 1e5;
constint MOD = 1e9 + 3;
ll gcd(ll a, ll b){ for (; b; a %= b, swap(a, b)); return a; }
int n, m;
int cnt = 0, ans = 0;
int card[101];
voidsum(int cur, int prev_sum, int cnt){
if (cnt == 3) {
if (prev_sum <= m) ans = max(ans, prev_sum);
return;
}
for (int i = cur; i < n; ++i) sum(i + 1, prev_sum + card[i], cnt + 1);
return;
}
intmain(){
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> card[i];
sum(0, 0, 0);
cout << ans;
}
2. 3중 for문
#include<bits/stdc++.h>usingnamespace std;
typedeflonglong ll;
constint INF = 2147483647;
constint MAX = 1e5;
constint MOD = 1e9 + 3;
ll gcd(ll a, ll b){ for (; b; a %= b, swap(a, b)); return a; }
int card[101];
intsolve(int n, int m){
int ans = 0;
for (int i = 0; i < n; ++i) for (int j = i + 1; j < n; ++j) for (int k = j + 1; k < n; ++k) {
if (card[i] + card[j] + card[k] == m) return m;
elseif(card[i] + card[j] + card[k] < m) ans = max(ans, card[i] + card[j] + card[k]);
}
return ans;
}
intmain(){
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, m;
cin >> n >> m;
for (int i = 0; i < n; ++i)cin >> card[i];
cout << solve(n, m);
return0;
}