Gangseok Lee
SW R&D Center, Samsung Electronics
이강석(gangseok514@gmail.com)
https://www.acmicpc.net
int gcd(int a, int b) {
int great_common_divisor = 1;
for (int k = 1; k <= a && k <= b; ++k) {
if (a % k == 0 && b % k == 0) {
great_common_divisor = k;
}
}
return great_common_divisor;
}
int sum = 0;
for (int i=1; i<=N; i++) {
sum += i;
}
int sum = 0;
sum = N*(N+1)/2;
int sum = 0;
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
if (i == j) {
sum += j;
}
}
}
int n;
char a;
char s[100];
scanf("%d", &n); // 숫자 입력 받기
scanf("%c", &a); // 문자 입력 받기
scanf("%s", s); // 문자열 입력 받기
int x, y;
scanf("%d%d", &x, &y); // 숫자 2개 입력 받기
int age;
char name[100];
// 나이(숫자)와 이름(문자열) 입력 받기
scanf("%d%s", &age, name);
int n;
char a;
char s[100];
for(int i = 0; i < N; i++) {
scanf("%1d", &n); // 1자리씩 입력받기
scanf("%10s", s); // 10개 문자단위씩 입력받기
}
if(scanf("%d", &n) > 0) { // 입력이 들어왔을때
printf("Hello");
}
/*
a
b
처럼 들어왔을때 ab 를 각각 받아야 한다면
*/
for(int i = 0; i < N; i++) {
// %c 앞에 공백을 넣는다(n을 무시하기 위함, 하지만 컴파일 환경이 윈도우라면?)
scanf(" %c", &a);
}
printf("Hello world!\n"); // 개행문자는 '\n'
printf("%d + %d = %d\n", 1, 2, 1 + 2); // 1 + 2 = 3
printf("%d", x); // int 변수값 출력하기
printf("%s", s); // 문자열 변수값 출력하기
for (int tc = 1; tc <= TC; ++tc) {
printf("Case #%d: %d\n", solve());
}
int main() {
int TC;
scanf("%d", &TC);
for (int tc = 1; tc <= TC; ++tc) {
int x;
scanf("%d", &x);
printf("Case #%d: %d\n", tc, x * x);
}
return 0;
}
// 템플릿을 사용하여 범용성 있게
template<typename T>
// 레퍼런스를 사용하여 빠르게
void swap(T& a, T& b) {
T t = a;
a = b;
b = t;
}
float f = 278.90f;
int i = f*100;
printf("%d", i);
float f = 278.90f;
int i = (f*100 + 0.5);
printf("%d", i);
const int MAX_N = 1000;
int N;
int A[MAX_N + 1][MAX_N + 1];
int main() {
...
return 0;
}
#if 1
#define PA(X, ...) printf(X, __VA_ARGS__)
#define P(X) printf(X)
#else
#define PA(X, ...)
#define P(X)
#endif
int main() {
P("Hello!");
PA(" %s", "world");
}
#include <ctime> or <time.h>
clock_t t1, t2;
t1 = clock();
{
Code
}
t2 = clock();
printf("time: %lf\n", (double)(t2-t1)/CLOCKS_PER_SEC);
int GCD(int a, int b) {
while(b != 0) {
int r = a % b;
a = b;
b = r;
}
return a;
}
※ 두 수의 크기 순서는 고려하지 않아도 된다.
int GCD(int a, int b) {
return b == 0 ? a : GCD(b, a % b);
}
※ 호출 횟수는 숫자가 커져도 많지 않으므로 고려하지 않아도 된다
Text
bool prime(int n) {
if (n < 2) return false;
for (int i = 2; i*i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
int N;
int a[1000], n;
for(int i = 0; i < N; i++) {
scanf("%d", &n);
a[n]++;
}
for(int i = 0; i < 1000; i++) {
printf("%d ", a[i]);
}
int sum(int i, int j) {
int res = 0;
for (int n = i; n <= j; n++) {
res += A[i];
}
return res;
}
const int MAX_N = 10000;
int S[MAX_N + 1];
// O(n)
int prefixSum(int n) {
for (int i = 1; i <= n; ++i) {
S[i] += S[i - 1];
}
}
// O(1)
int sum(int i, int j) {
return S[j] - S[i - 1];
}
// 북 > 동 > 남 > 서 순으로 기입
int dx[] = { 0, 1, 0, -1 };
int dy[] = { -1, 0, 1, 0 };
int f(int x, int y) {
for(int i = 0; i < 4; i++) {
f(x + dx[i], y + dy[i]);
}
}
const int MAX = 1000;
int stack[MAX + 1];
int stack_top;
void stack_init() {
// 스택이 비어있는 상황이니 0으로 초기화
stack_top = 0;
}
int size() {
// top값 자체가 사이즈를 의미한다. top 인덱스에는 항상 값이 비어있다.
return stack_top;
}
bool empty() {
// 0이면 스택은 비어있다.
return stack_top == 0;
}
void push(int x) {
// 현재 인덱스 기준으로 스택에 값을 넣은 다음 stack_top값을 증가시킨다.
// 즉, 현재 가리키고 있는 인덱스는 비어있다.
stack[stack_top++] = x;
}
int pop() {
// 마지막에 넣은 값은 stack_top보다 1작은 인덱스에 저장되어 있다.
// 그러므로 감소시킨 인덱스의 값을 리턴해야한다.
return stack[--stack_top];
}
const int MAX = 10000;
int queue[MAX + 1];
int head; // head는 큐의 맨 앞의 값을 가진 인덱스이다.
int tail; // tail은 큐의 마지막 값의 다음 인덱스를 말한다.
int size() {
return tail - head;
}
bool empty() {
return head == tail;
}
void push(int x) {
// tail은 비어있으니 넣고나서 증가시킨다.
queue[tail++] = x;
}
void pop() {
// head는 맨 앞 값이니 리턴하고 증가시킨다.
return queue[head++];
}
void bubbleSort(int A[], int len) {
for (int i = 0; i < len; ++i)
for (int j = 1; j < len; ++j)
if (A[j - 1] > A[j])
swap(A[j - 1], A[j]);
}
void selectionSort(int A[], int len) {
int min = 0;
for (int i = 0; i < len-1; ++i) {
min = i;
for (int j = i + 1; j < len; ++j) {
if (A[min] > A[j]) {
min = j;
}
}
if(min != i) swap(A[i], A[min]);
}
}
k | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
값 | 3 | 6 | 2 | 5 | 1 | 8 |
int m = a[i];
for(int k = i; k <= j; k++) {
if(m > a[k]) {
m = a[k];
}
}
i\j | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
0 | 3 | 3 | 2 | 2 | 1 | 1 |
1 | 6 | 2 | 2 | 1 | 1 | |
2 | 2 | 2 | 1 | 1 | ||
3 | 5 | 1 | 1 | |||
4 | 1 | 1 | ||||
5 | 8 |
k | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
값 | 3 | 6 | 2 | 5 | 1 | 8 |
int d[N][N];
int a[N];
int n;
for (int i = 0; i < n; i++) {
d[i][i] = a[i];
for(int j = i + 1; j < n; j++) {
d[i][j] = min(d[i][j - 1], a[j]);
}
}
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
3 | 6 | 2 | 5 | 3 | 1 | 8 | 9 | 7 | 3 |
G[0] = 2 | G[1] = 1 | G[2] = 7 | 3 |
---|
for (int i = 0; i < n; i++) {
if (i % r == 0) {
g[i / r] = a[i];
} else {
g[i / r] = min(g[i / r], a[i]);
}
}
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
3 | 6 | 2 | 5 | 3 | 1 | 8 | 9 | 7 | 3 |
G[0] = 2 | G[1] = 1 | G[2] = 7 | 3 |
---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
3 | 6 | 2 | 5 | 3 | 1 | 8 | 9 | 7 | 3 |
G[0] = 2 | G[1] = 1 | G[2] = 7 | 3 |
---|
// A[1] 부터 A[2] 까지만
while (true) {
if(start % r == 0) break;
ans = min(ans, a[start]);
start += 1;
}
// A[9] 만(반대로 체크)
while (true) {
if(end % r == r - 1) break;
ans = min(ans, a[end]);
end += 1;
}
// G 체크
for (int i = start / r; i <= end / r; i++) {
ans = min(ans, group[i]);
}
int fib(int k) {
// base cases
if (k == 0) return 0;
if (k == 1) return 1;
// others
return fib(k - 1) + fib(k - 2);
}
k
k-1
A
C
B
k
k-1
A
C
B
k
k-1
A
C
B
k
k-1
A
C
B
// k 개의 원반을 from에서 to로 옮기는 함수
hanoi(k, from, to, spare)
if k == 1
move from into to
else
// k-1개의 원반을 from에서 spare로 옮긴다
hanoi(k-1, from, spare, to)
// 가장 아래 남은 원반 하나를 from에서 to로 옮긴다
hanoi(1, from, to, spare)
// 다시 k-1개의 원반을 spare에서 to로 옮긴다
hanoi(k-1, spare, to, from)
int N;
int MAX_N = 4;
int point[MAX_N]; // 만족도
int price[MAX_N]; // 가격
int max_point; // 최대 만족도
int max_price = 30000;
int select(int i, int pr, int po) {
if (pr > max_price) return; // 최대 가격을 넘으면 종료
if (i == N) { // 마지막 원소까지 다 확인한 경우
if (max_point < po) max_point = po; // 최대치 갱신
} else {
// i번째 메뉴를 선택하는 경우
select(i + 1, pr + price[i], po + point[i]);
// i번째 메뉴를 선택하지 않는 경우
select(i + 1, pr, po);
}
}
select(0, 0, 0);
divideAndConquer(problem)
if 풀 수 있을 만큼 작다면
- 해당 범위를 풀고 값을 리턴 : base case
else
- 문제 구간을 나눈다.
- 나눈 구간으로 재귀호출을 한다. : divide
- 각각 나눈 구간의 결과를 합친다. : merge
- 합친 결과에서 값을 도출한다.
- 값을 리턴한다.
const int MOD = 1000000007;
// calculate (n^p) % MOD in O(p)
int pow(int n, int p) {
int ans = 1;
for (int i = 0; i < p; ++i) {
ans = (ans * n) % MOD;
}
return ans;
}
const int MOD = 1000000007;
// calculate (n^p) % MOD in O(log p)
int pow(int n, int p) {
if (p == 0) {
return 1;
} else {
int res = pow(n, p / 2);
int ans = (res * res) % MOD;
if (p % 2 == 1) {
ans = (ans * n) % MOD;
}
return ans;
}
}
sort(start, end) {
if start == end
return
if start + 1 == end and a[start] > a[end]
swap(a[start], a[end])
return
mid = (start + end) / 2
sort(start, mid)
sort(mid + 1, end)
merge(start, end)
}
merge(start, end) {
mid = (start + end) / 2
i = start, j = mid + 1, k = 0
while i <= mid && j <= end
if a[i] <= a[j]
b[k++] = a[i++]
else
b[k++] = a[j++]
while i <= mid
b[k++] = a[i++]
while j <= end
b[k++] = a[j++]
for i = start to i <= end
a[i] = b[i - start]
}
while (lower_bound <= upper_bound) {
int mid = (lower_bound + upper_bound) / 2;
if (test(mid) == true) {
answer = mid;
upper_bound = mid - 1;
} else {
lower_bound = mid + 1;
}
}
아이유
장기하
박명수
유재석
양평이형
유인나
1 2 3 4 5 6
아이유 1 0 1 1 1 1 0
유재석 2 1 0 0 1 1 0
유인나 3 1 0 0 0 0 0
장기하 4 1 1 0 0 0 1
박명수 5 1 1 0 0 0 0
양평형 6 0 0 0 1 0 0
1 2 3 4 5 6
아이유 1 0 1 1 1 1 0
유재석 2 1 0 0 1 1 0
유인나 3 1 0 0 0 0 0
장기하 4 1 1 0 0 0 1
박명수 5 1 1 0 0 0 0
양평형 6 0 0 0 1 0 0
int V; // 정점의 수
int E; // 간선의 수
int G[MAX_V + 1][MAX_V + 1]; // 인접행렬
scanf("%d", &V);
scanf("%d", &E);
for (int i = 0; i < E; ++i) {
int u, v;
scanf("%d%d", &u, &v);
G[u][v] = 1; // 정점 u와 v는 연결
G[v][u] = 1; // 정점 v와 u는 연결
}
서울
인천
천안
대전
대구
부산
경주
전주
광주
여수
50
60
95
48
42
63
45
44
60
78
84
127
108
1 2 3 4 5 6 7 8 9 10
1 0 50 60 -1 -1 -1 -1 -1 -1 -1
2 50 0 -1 -1 -1 -1 -1 -1 -1 -1
3 60 -1 0 95 -1 42 -1 -1 -1 -1
4 -1 -1 95 0 48 -1 -1 -1 -1 -1
5 -1 -1 -1 48 0 -1 108 -1 -1 -1
6 -1 -1 42 -1 -1 0 -1 63 -1 -1
7 -1 -1 -1 -1 108 -1 0 84 -1 127
8 -1 -1 -1 -1 -1 63 84 0 45 60
9 -1 -1 -1 -1 -1 -1 -1 45 0 44
10 -1 -1 -1 -1 -1 -1 127 60 44 0
1: 서울, 2: 인천, 3: 천안, 4: 전주, 5: 광주
6: 대전, 7: 여수, 8: 대구, 9: 경주, 10: 부산
int V; // 정점의 수
int E; // 간선의 수
int G[MAX_V + 1][MAX_V + 1]; // 인접행렬
scanf("%d", &V);
scanf("%d", &E);
// 인접행렬 초기화
for (int i = 0; i < V; ++i) {
for (int j = 0; j < V; ++j) {
G[i][j] = -1;
}
G[i][i] = 0;
}
// 간선을 입력 받아 인접행렬을 채운다
for (int i = 0; i < E; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
G[u][v] = w;
G[v][u] = w;
}
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
A
B
C
E
D
F
G
bool visited[MAX_N + 1];
void DFS(int u) {
// 이미 방문했는지 검사
if (visited[u]) {
return;
}
// u번째 정점을 지금 방문함
visited[u] = true;
printf("%d\n", u);
// 인접한 정점을 방문
for (int v = 1; v <= N; ++v) {
if (v == u) continue; // 자신은 건너뜀
if (A[u][v]) {
DFS(v);
}
}
}
int Y, X;
map[MAX_ROW + 1][MAX_COL + 1];
visited[MAX_ROW + 1][MAX_COL + 1];
// 상 > 하 > 좌 > 우
int dx[] = { 0, 0, -1, 1 };
int dy[] = { -1, 1, 0, 0 };
void dfs(int y, int x) {
// 지도의 경계를 벗어나는지 검사
if (y < 0 || y >= Y || x < 0 || x >= X) {
return;
}
// 이미 방문했는지 검사
if (visited[y][x]) {
return;
}
// (y, x)를 방문
visited[y][x] = true;
printf("%d %d\n", y, x);
for(int i = 0; i < 4; i++) {
dfs(y + dy[i], x + dx[i]);
}
}
A
B
C
E
D
F
G
A
B
C
E
D
F
G
1
A
B
C
E
D
F
G
1
2
2
A
B
C
E
D
F
G
1
2
3
2
3
A
B
C
E
D
F
G
1
2
3
2
3
A
B
C
E
D
F
G
1
2
3
2
3
4
A
B
C
E
D
F
G
1
2
3
2
3
4
4
A
B
C
E
D
F
G
1
2
3
2
3
4
4
A
B
C
E
D
F
G
1
2
3
2
3
4
4
A
B
C
E
D
F
G
1
2
3
2
3
4
4
push(start); // 시작 지점을 큐에 넣음
int step = 0;
while (!queueIsEmpty()) {
step++; // 시작정점에서의 거리
// 현재 큐에 들어있는 모든 노드는 같은 거리에 있다.
int queue_size = size();
for (int i = 0; i < queue_size; ++i) {
int u = pop();
printf("%d\n", u);
for (int v = 1; v <= N; ++v) {
if (u != v && G[u][v] && visited[v] == false) {
push(v);
visited[v] = true;
}
}
}
}
dy[] = { 1, 0, -1, 0 };
dx[] = { 0, 1, 0, -1 };
push(startPoint);
int step = 0;
while (!queueIsEmpty()) {
step++;
int queue_size = queueSize();
for (int i = 0; i < queue_size; ++i) {
Point p = pop();
printf("%d %d\n", p.x, p.y);
for (int d = 0; d < 4; ++d) {
Point next;
next.x = p.x + dx[d];
next.y = p.y + dy[d];
if(visited[next.y][next.x] == false) {
push(next);
visited[next.y][next.x] = true;
}
}
}
}
By Gangseok Lee
Algorithm Problem Solving 기초