-- 1. 모든 레코드 조회하기SELECT*from animal_ins orderby animal_id asc-- 2. 역순 정렬하기SELECT Name, datetime from animal_ins orderby animal_id desc-- 3. 아픈 동물 찾기SELECT animal_id, name from animal_ins where intake_condition = "Sick" orderby animal_id asc ;
-- 4. 어린 동물 찾기SELECT animal_id, name from animal_ins wherenot intake_condition = "aged" orderby animal_id ASC-- 5. 동물의 아이디와 이름SELECT animal_id, name from animal_ins orderby animal_id asc-- 6. 여러 기준으로 정렬하기SELECT animal_id, name, datetime from animal_ins orderby name asc, datetime desc-- 7. 상위 n개 레코드SELECT name from animal_ins orderby datetime asc limit 1
-- 1. 최댓값 구하기SELECT datetime from animal_ins orderby datetime desc limit 1-- 2. 최솟값 구하기SELECTmin(datetime) from animal_ins
-- 3. 동물 수 구하기SELECTcount(animal_id) from animal_ins;
-- 4. 중복 제거하기SELECTdistinct(name) from animal_ins
-- 1. 고양이와 개는 몇마리 있을까SELECT animal_type, count(animal_id) as count from animal_ins groupby animal_type orderby animal_type asc-- 2. 동명 동물 수 찾기SELECT name, count(name) as count from animal_ins groupby name havingcount(name) >=2orderby name asc-- 3. 입양 시작 구하기 (1)selectHOUR(datetime) ashour, count(datetime) as count
from animal_outs
groupbyhourhavinghour>=9andhour<20orderbyhourasc-- 4. 입양 시각 구하기 (2)SET@h=-1;
SELECT (@h :=@h+1) ashour,
(selectcount(hour(datetime)) from animal_outs wherehour(datetime) =@h) as count
from animal_outs where@h<23
-- 1. 이름이 없는 동물의 아이디SELECT animal_id from animal_ins where name isNULL-- 2. 이름이 있는 동물의 아이디SELECT animal_id from animal_ins where name isnotnullorderby animal_id asc-- 3. NULL 처리하기SELECT animal_type, ifnull(name, "No name") as name, sex_upon_intake from animal_ins;
-- 1. 없어진 기록 찾기SELECT outs.animal_id, outs.name from animal_outs outs
leftouterjoin animal_ins ins
on outs.animal_id = ins.animal_id
where ins.animal_id isnullorderby outs.animal_id asc-- 2. 있었는데요 없었습니다SELECT ins.animal_id, ins.name from animal_ins ins
join animal_outs outs on ins.animal_id = outs.animal_id
where ins.datetime > outs.datetime
orderby ins.datetime asc-- 3. 오랜 기간 보호한 동물 (1)select ins.name, ins.datetime from animal_ins ins
leftjoin animal_outs outs
on ins.animal_id = outs.animal_id
where outs.animal_id isnullorderby ins.datetime asc
limit 3-- 4. 보호소에서 중성화한 동물SELECT ins.animal_id, ins.animal_type, ins.name from animal_ins ins
leftjoin animal_outs outs
on ins.animal_id = outs.animal_id
where (outs.sex_upon_outcome like'%Spayed%'or outs.sex_upon_outcome like'%Neutered%')
and ins.sex_upon_intake like'%Intact%'orderby ins.animal_id asc
-- 1. 루시와 엘라 찾기 SELECT animal_id, name, sex_upon_intake from animal_ins
where name="Lucy" or name="Ella" or name="Pickle" or name="Rogan" or name="Sabrina" or name="Mitty"
orderby animal_id asc-- 2. 이름에 el이 들어가는 동물 찾기SELECT animal_id, name from animal_ins
wherelower(name) like "%el%" and animal_type = "Dog"
orderby name asc-- 3. 중성화 여부 파악하기SELECT animal_id, name,
casewhen (SEX_UPON_INTAKE LIKE'%NEUTERED%'OR SEX_UPON_INTAKE LIKE'%SPAYED%')then'O'else'X'endfrom animal_ins
orderby animal_id asc-- 4. 오랜 기간 보호한 동물 (2)SELECT ins.animal_id, ins.name from animal_ins ins, animal_outs outs
where ins.animal_id = outs.animal_id
orderby datediff(outs.datetime, ins.datetime) desc
limit 2-- 5. DATETIME에서 DATE로 형 변환SELECT animal_id, name, DATE_FORMAT(datetime, '%Y-%m-%d') as 날짜 from animal_ins
orderby animal_id asc
탐색 알고리즘인 DFS(Depth First Search, 깊이 우선 탐색) 알고리즘에 대해 이해하고 직접 구현
탐색 알고리즘인 BFS(Breadth First Search, 너비 우선 탐색) 알고리즘에 대해 이해하고 직접 구현
인접리스트와 인접 행렬
그래프
위 와 같은 그래프가 있을 때, 이 그래프를 표현하는 방식은 크게 2가지(인접리스트, 인접행렬)가 있다.
각 표현 방식을 구현해보면 다음 코드와 같다.
1) 간선을 인접리스트로 변환
#include<iostream>#include<cstring>#include<vector>#include<map>usingnamespace std;
// 만들어진 그래프를 출력voidprint_adjacency_list(map<int, vector<int>> graph){
for (auto node : graph) {
cout << node.first << " : ";
for (auto ns : node.second) {
cout << ns << " ";
}
cout << "\n";
}
}
intmain(){
int n, m, u, v;
// 최초 입력 받기
cin >> n >> m >> start_node;
// 그래프를 인접리스트 형식으로 표현
map<int, vector<int>> graph;
// 간선의 개수만큼 노드에 추가for (int i = 0; i < m; i++) {
cin >> u >> v;
// 각 노드별로 연결된 간선을 서로 추가(무방향 또는 양방향 그래프)
graph[u].push_back(v);
graph[v].push_back(u);
}
// 생성된 인접리스트 출력print_adjacency_list(graph);
return0;
}
출력 결과
2) 간선을 인접행렬로 변환
#include<iostream>usingnamespace std;
intmain(){
int n, m, u, v;
cin >> n >> m;
// 인접행렬 생성int** graph = newint* [n];
for (int i = 0; i < n; i++) {
graph[i] = newint[n];
}
// 인접행렬 초기화for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
graph[i][j] = 0;
}
}
// 간선 입력for (int i = 0; i < m; i++) {
cin >> u >> v;
u--;
v--;
// 무방향 그래프
graph[u][v] = graph[v][u] = 1;
}
// 인접행렬 출력for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << graph[i][j] << " ";
}
cout << "\n";
}
return0;
}
출력 결과
3) 인접행렬을 문자열로 입력받기
#include<iostream>usingnamespace std;
intmain(){
int n;
string str;
cin >> n;
int** map = newint* [n];
for (int i = 0; i < n; i++) {
str = "";
map[i] = newint[n];
cin >> str;
for (int j = 0; j < str.length(); j++) {
map[i][j] = str[j] - '0';
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j< n; j++) {
cout << map[i][j];
}
cout << "\n";
}
return0;
}
출력 결과
4) 인접행렬을 인접리스트로 변환
#include<iostream>#include<vector>usingnamespace std;
vector<int> *Convert_adjMatrix_to_adjList(int n, int** matrix){
vector<int> * adjlist = new vector<int>[n+1];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 1 && i != j) {
adjlist[i+1].push_back(j+1);
}
}
sort(adjlist[i+1].begin(), adjlist[i+1].end());
}
return adjlist;
}
intmain(){
int n;
string str;
cin >> n;
int** map = newint* [n];
for (int i = 0; i < n; i++) {
str = "";
map[i] = newint[n];
cin >> str;
for (int j = 0; j < str.length(); j++) {
map[i][j] = str[j] - '0';
}
}
vector<int> *adl = Convert_adjMatrix_to_adjList(n, map);
for (int i = 1; i <= n; i++) {
cout << i << " : ";
for (auto node : adl[i]) {
cout << node << " ";
}
cout << "\n";
}
return0;
}
출력 결과
DFS (깊이 우선 탐색)
1 2 4 3 5
재귀로 DFS 구현
#include<iostream>#include<cstring>#include<vector>#include<map>usingnamespace std;
voiddfs_recursion(int n, vector<int>* graph, bool* visited){
cout << "start\nCurrent Node : " << n << "";
// 시작노드의 방문 여부를 체크
visited[n] = true;
for (auto node : graph[n]) {
cout << "\nN : " << n << ", Node : " << node << ", Visited : " << visited[node] << " ";
// 노드가 방문이 되어있는지 확인if (!visited[node]) {
cout << "-> Next node : " << node << "\n";
// 방문 안된 노드의 키값을 넣음func_1260_dfs_recursion(node, graph, visited);
}
}
cout << "\nend";
}
intmain(){
int n, m, start_node, u, v;
cin >> n >> m >> start_node;
vector<int> *graph = new vector<int>[n+1];
bool *visited = newbool[n+1];
memset(visited, 0, sizeof(bool) * (n+1));
for (int i = 0; i < m; i++) {
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
/*
// 오름차순으로 각 벡터를 정렬시킴 (이부분 주석 해제 시 1 2 3 4 5 순서로 진행)
for (int i = 1; i <= n; i++) {
sort(graph[i].begin(), graph[i].end());
}
*/dfs_recursion(start_node, graph, visited);
return0;
}
재귀 방식 코드 결과
스택으로 DFS 구현
//
BFS (너비 우선 탐색)
1 2 5 3 4
큐로 BFS 구현
#include<iostream>#include<cstring>#include<vector>#incldue<queue>usingnamespace std;
voidbfs_queue(int n, vector<int> * graph, bool* visited){
queue<int> q;
int now_node;
visited[n] = true;
q.push(n);
while (!q.empty()) {
now_node = q.front();
q.pop();
cout << now_node << " ";
for (auto node : graph[now_node]) {
if (!visited[node]) {
visited[node] = true;
q.push(node);
}
}
}
cout << "\n";
}
intmain(){
int n, m, start_node, u, v;
cin >> n >> m >> start_node;
vector<int> *graph = new vector<int>[n+1];
bool *visited = newbool[n+1];
memset(visited, 0, sizeof(bool) * (n+1));
for (int i = 0; i < m; i++) {
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
for (int i = 1; i <= n; i++) {
sort(graph[i].begin(), graph[i].end());
}
bfs_queue(start_node, graph, visited);
return0;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// OpenCV 사용을 위한 usingusing OpenCvSharp;
using OpenCvSharp.WpfExtensions;
// Timer 사용을 위한 usingusing System.Windows.Threading;
namespace WPF
{
// OpenCvSharp 설치 시 Window를 명시적으로 사용해 주어야 함 (window -> System.Windows.Window)public partial classMainWindow : System.Windows.Window
{
// 필요한 변수 선언
VideoCapture cam;
Mat frame;
DispatcherTimer timer;
bool is_initCam, is_initTimer;
publicMainWindow(){
InitializeComponent();
}
privatevoidwindows_loaded(object sender, RoutedEventArgs e){
// 카메라, 타이머(0.01ms 간격) 초기화
is_initCam = init_camera();
is_initTimer = init_Timer(0.01);
// 초기화 완료면 타이머 실행if(is_initTimer && is_initCam) timer.Start();
}
privateboolinit_Timer(double interval_ms){
try
{
timer = newDispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(interval_ms);
timer.Tick += newEventHandler(timer_tick);
returntrue;
}
catch
{
returnfalse;
}
}
privateboolinit_camera(){
try {
// 0번 카메라로 VideoCapture 생성 (카메라가 없으면 안됨)
cam = newVideoCapture(0);
cam.FrameHeight = (int)Cam_1.Height;
cam.FrameWidth = (int)Cam_1.Width;
// 카메라 영상을 담을 Mat 변수 생성
frame = newMat();
returntrue;
}catch{
returnfalse;
}
}
privatevoidtimer_tick(object sender, EventArgs e){
// 0번 장비로 생성된 VideoCapture 객체에서 frame을 읽어옴
cam.Read(frame);
// 읽어온 Mat 데이터를 Bitmap 데이터로 변경 후 컨트롤에 그려줌
Cam_1.Source = OpenCvSharp.WpfExtensions.WriteableBitmapConverter.ToWriteableBitmap(frame);
}
}
}
#include<iostream>usingnamespace std;
intmain(){
int n, m, sum, min, res = 0;
cin >> n >> m;
int* card = newint[n];
bool is_flag;
for (int i = 0; i < n; i++) {
cin >> card[i];
}
sum = 0;
min = m;
is_flag = true;
for (int i = 0; i < n - 1 && is_flag; i++) {
for (int j = i + 1; j < n && is_flag; j++) {
for (int k = j + 1; k < n && is_flag; k++) {
sum = card[i] + card[j] + card[k];
if (sum == m) is_flag = false;
if (min > m - sum && m >= sum) {
min = m - sum;
res = sum;
}
}
}
}
cout << res << endl;
return0;
}
문제 2. 분해합 (브론즈 2)
#include<iostream>#include<string>#include<cmath>#include<map>usingnamespace std;
intfunc_2231_create_decompose(int a){
int len, res = a;
len = to_string(a).length();
for (int i = len; a > 0; i--) {
res += a / pow(10, i);
a %= (int)pow(10, i);
}
return res;
}
intmain(){
int a, key;
cin >> a;
map<int, int> m;
for (int i = 1; i < a; i++) {
key = func_2231_create_decompose(i);
if(!m[key])
m[key] = i;
}
cout << m[a];
return0;
}
문제 3. 덩치 (실버 5)
/*
* 문제 내용 이해가 중요한 문제였음.
* map을 사용해서 구현한 버전
*/#include<iostream>#include<map>usingnamespace std;
intmain(){
int int_case;
int cnt, grade;
int* bulk;
cin >> int_case;
map<char, int *> m_input;
// 입력for (int i = 0; i < int_case; i++) {
bulk = newint[2];
cin >> bulk[0] >> bulk[1];
m_input['a' + i] = bulk;
}
// 등수 : 나보다 덩치가 큰 사람의 수 + 1for (int i = 0; i < int_case; i++) {
cnt = 1;
for (int j = 0; j < int_case; j++) {
// 덩치 : 키도 크고, 몸무게도 무거운 사람 수if (m_input['a' + i][0] < m_input['a' + j][0] && m_input['a' + i][1] < m_input['a' + j][1]) {
cnt++;
}
}
// 등수 출력
cout << cnt << " ";
}
for (int i = 0; i < int_case; i++) {
delete m_input['a' + i];
}
return0;
}
/*
* 문제 내용 이해가 중요한 문제였음.
* 2차원 Array를 사용해서 구현한 버전
*/#include<iostream>usingnamespace std;
intmain(){
int int_case, cnt;
cin >> int_case;
int** arr = newint*[int_case];
int* bulk;
for (int i = 0; i < int_case; i++) {
bulk = newint[2];
cin >> bulk[0] >> bulk[1];
arr[i] = bulk;
}
for (int i = 0; i < int_case; i++) {
cnt = 1;
for (int j = 0; j < int_case; j++) {
if (arr[i][0] < arr[j][0] && arr[i][1] < arr[j][1]) {
cnt++;
}
}
cout << cnt << " ";
}
return0;
}
문제 4. 체스판 다시 칠하기 (실버 5)
#include<iostream>#include<cstring>usingnamespace std;
intfunc_1018_bitmask(char **_map){
int cnt_1 = 0, cnt_2 = 0;
char filter_1[8][8] = {
{0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0}
};
char filter_2[8][8] = {
{1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1}
};
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if ( !(_map[i][j]^filter_1[i][j]) ) {
cnt_1++;
}
if (!(_map[i][j] ^ filter_2[i][j])) {
cnt_2++;
}
}
}
if (cnt_1 >= cnt_2) return cnt_2;
elsereturn cnt_1;
}
intmain(){
int n, m;
int min, cnt;
string tmp;
cin >> n >> m;
char** tmp_map = newchar* [8];
for (int i = 0; i < 8; i++) {
tmp_map[i] = newchar[8];
}
char** bwmap = newchar* [n];
for (int i = 0; i < n; i++) {
bwmap[i] = newchar[m];
}
for (int i = 0; i < n; i++) {
cin >> tmp;
for (int j = 0; j < m; j++) {
if (tmp[j] == 'B') {
bwmap[i][j] = 1;
}
else {
bwmap[i][j] = 0;
}
}
}
cnt = 0;
min = 64;
for (int i = 0; i <= n - 8; i++) {
for (int j = 0; j <= m - 8; j++) {
for (int a = i, aa = 0; a < i + 8; a++, aa++) {
for (int b = j, bb = 0; b < j + 8; b++, bb++) {
tmp_map[aa][bb] = bwmap[a][b];
}
}
cnt = func_1018_bitmask(tmp_map);
if (cnt < min) {
min = cnt;
}
}
}
cout << min << "\n";
return0;
}
문제 5. 영화감독 숌 (실버 5)
#include<iostream>#include<cstring>usingnamespace std;
intmain(){
int n, cnt=0;
string tmp;
cin >> n;
for (int i = 666; i < 2100000000; i++) {
tmp = to_string(i);
if (tmp.find("666") != string::npos) {
cnt++;
if (cnt > 10000) break;
if (cnt == n) {
cout << tmp << "\n";
}
}
}
}