조일용
어제는 못 풀었던 문제를 오늘은 풀 수 있으면 성공
가장 중요
int sumToN(int n) {
int sum = 0;
for (int i = 1; i <= n; ++i) {
sum += i;
}
return sum;
}
int sumToN(int n) {
int sum = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= i; ++j) {
sum += 1;
}
}
return sum;
}
int sumToN(int n) {
return n * (n + 1) / 2
}
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 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); // 나이(숫자)와 이름(문자열) 입력 받기
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;
}
const int MAX_N = 1000;
int N;
int A[MAX_N + 1][MAX_N + 1];
int main() {
...
return 0;
}
int a = 2147483647; // maximum value of integer
int b = a + 1; // b = -2147483648 not 2147483648
int c = a + 2; // c = -2147483647
int a = 32768;
long long b = a; // b = 32768
short c = a; // c = -32768
int asciiDigitToNumber(char x) {
// x >= '0' && x <= '9'
return x - '0';
}
char numberDigitToAscii(int x) {
// x >= 0 && x <= 9
return x + '0';
}
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
printf("%d\n", a[0]); // 1
printf("%d\n", a[1]); // 2
char a[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
char b[] = "world";
printf("%s %s\n", a, b); // hello world
int strlen(char* s) {
int len = 0;
while (s[len]) {
len++;
}
return len;
}
void toCapitalCase(char* s) {
for (int i = 0; s[i]; ++i) {
if (s[i] >= 'a' && s[i] <= 'z') {
s[i] -= 32;
}
}
}
void toLowerCase(char* s) {
for (int i = 0; s[i]; ++i) {
if (s[i] >= 'A' && s[i] <= 'Z') {
s[i] += 32;
}
}
}
while (n > 0) {
int k = n % 10;
// do something with k
...
n /= 10;
}
// O(n)
int sum(int A[], int p, int q) {
int res = 0;
for (int i = p; i <= q; ++i) {
res += A[i];
}
}
const int MAX_N = 10000;
int S[MAX_N + 1];
// O(n)
int suffixSum(int A[], int n) {
S[0] = 0;
for (int i = 0; i < n; ++i) {
S[i + 1] = S[i] + A[i];
}
}
// O(1)
int sum(int p, int q) {
return S[q + 1] - S[p];
}
const int MAX_STACK_SIZE = 1000;
int stack[MAX_STACK_SIZE + 1];
int stack_top;
void stackInit() {
stack_top = 0;
}
int stackSize() {
return stack_top;
}
bool stackIsEmpty() {
return stack_top == 0;
}
void stackPush(int x) {
stack[stack_top++] = x;
}
int stackPop() {
return stack[--stack_top];
}
const int MAX_QUEUE_SIZE = 10000;
int queue[MAX_QUEUE_SIZE + 1];
int queue_head;
int queue_tail;
void queueInit() {
queue_head = queue_tail = 0;
}
int queueSize() {
return queue_tail - queue_head;
}
bool queueIsEmpty() {
return queueSize() == 0;
}
void queuePush(int x) {
queue[queue_tail++] = x;
}
int queuePop() {
return queue[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]);
}
}
}
}
int count[MAX_N + 1];
int countSort(int A[], int len) {
for (int i = 0; i < MAX_N; ++i) {
count = 0;
}
for (int i = 0; i < len; ++i) {
count[A[i]]++;
}
for (int v = 0, idx = 0; v <= MAX_VALUE; ++v) {
for (int i = 0; i < count[v]; ++i) {
A[idx++] = v;
}
}
}
int fib(int k) {
// base cases
if (k == 0) return 0;
if (k == 1) return 1;
// others
return fib(k - 1) + fib(k - 2);
}
A
B
C
k-1
kth
A
B
C
k-1
kth
A
B
C
k-1
kth
A
B
C
k-1
kth
// 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 S[MAX_N];
int max_value;
int dfs(int depth, int value) {
if (depth == N) { // 마지막 원소까지 다 확인한 경우
// 최대치 갱신
if (max_value < value) {
max_value = value;
}
} else {
// depth번째 아이템을 선택하는 경우
dfs(depth + 1, value + S[depth]);
// depth번째 아이템을 선택하지 않는 경우
dfs(depth + 1, value);
}
}
dfs(0, 0);
divideAndConquer(problem)
if able to solve the problem
solve it and return the answer
else
divide problem into subproblems
solve each subproblems by recursive call
merge answers of subproblems
reduce answer for the problem
return the answer
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;
}
}
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
종료 순서:
A
B
C
E
D
F
G
방문 순서: A B
종료 순서:
A
B
C
E
D
F
G
방문 순서: A B D
종료 순서:
A
B
C
E
D
F
G
방문 순서: A B D E
종료 순서:
A
B
C
E
D
F
G
방문 순서: A B D E C
종료 순서:
A
B
C
E
D
F
G
방문 순서: A B D E C
종료 순서: C
A
B
C
E
D
F
G
방문 순서: A B D E C G
종료 순서: C
A
B
C
E
D
F
G
방문 순서: A B D E C G
종료 순서: C G
A
B
C
E
D
F
G
방문 순서: A B D E C G
종료 순서: C G E
A
B
C
E
D
F
G
방문 순서: A B D E C G F
종료 순서: C G E
A
B
C
E
D
F
G
방문 순서: A B D E C G F
종료 순서: C G E F
A
B
C
E
D
F
G
방문 순서: A B D E C G F
종료 순서: C G E F D
A
B
C
E
D
F
G
방문 순서: A B D E C G F
종료 순서: C G E F D B
A
B
C
E
D
F
G
방문 순서: A B D E C G F
종료 순서: C G E F D B A
bool visited[MAX_N + 1];
bool finished[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);
}
}
// u번째 정점 방문을 마침
finished[u] = true;
}
int Y, X;
map[MAX_ROW + 1][MAX_COL + 1];
visited[MAX_ROW + 1][MAX_COL + 1];
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);
// 인접한 칸을 방문
dfs(y - 1, x);
dfs(y, x - 1);
dfs(y + 1, x);
dfs(y, x + 1);
}
A
B
C
E
D
F
G
A
B
C
E
D
F
G
방문 순서:
큐: A
1
A
B
C
E
D
F
G
방문 순서: A
큐: B C
1
2
2
A
B
C
E
D
F
G
방문 순서: A B
큐: C D E
1
2
2
3
3
A
B
C
E
D
F
G
방문 순서: A B C
큐: D E
1
2
2
3
3
A
B
C
E
D
F
G
방문 순서: A B C D
큐: E F
1
2
2
3
3
4
A
B
C
E
D
F
G
방문 순서: A B C D E
큐: F G
1
2
2
3
3
4
4
A
B
C
E
D
F
G
방문 순서: A B C D E F
큐: G
1
2
2
3
3
4
4
A
B
C
E
D
F
G
방문 순서: A B C D E F G
큐:
1
2
2
3
3
4
4
A
B
C
E
D
F
G
방문 순서: A B C D E F G
큐:
1
2
2
3
3
4
4
push(int v) {
if (visited[v] == false) {
pushQueue(v);
visited[v] = true;
}
}
...
push(start);
int step = 0;
while (!queueIsEmpty()) {
step++;
int queue_size = queueSize();
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]) {
push(v);
}
}
}
}
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];
push(next);
}
}
}
dy[] = { 2, 1, -1, -2, -2, -1, 1, 2};
dx[] = { 1, 2, 2, 1, -1, -2, -2, -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 < 8; ++d) {
Point next;
next.x = p.x + dx[d];
next.y = p.y + dy[d];
push(next);
}
}
}
for (int u = 1; u <= V; ++u) {
for (int v = 1; v <= V; ++v) {
D[u][v] = G[u][v];
}
}
for (int k = 1; k <= V; ++k) {
for (int u = 1; u <= V; ++u) {
for (int v = 1; v <= V; ++v) {
if (D[u][v] > D[u][k] + D[k][v]) {
D[u][v] = D[u][k] + D[k][v];
}
}
}
}
for (int u = 1; u <= V; ++u) {
for (int v = 1; v <= V; ++v) {
D[u][v] = G[u][v];
}
D[u][u] = false;
}
for (int k = 1; k <= V; ++k) {
for (int u = 1; u <= V; ++u) {
for (int v = 1; v <= V; ++v) {
if (D[u][k] && D[k][v]) {
D[u][v] = true;
}
}
}
}