diff --git "a/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1368.cpp" "b/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1368.cpp" new file mode 100644 index 0000000..1a296d1 --- /dev/null +++ "b/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1368.cpp" @@ -0,0 +1,68 @@ +#include +#include +#include + +using namespace std; + +//MST (프림) + +const double INF = 1e5 + 1; +typedef pair ci; + +int prim(int v, int start, vector> &graph) { + int sum = 0; + vector dist(v, INF); //각 정점까지의 비용 + vector visited(v, false); //정점 방문 여부 + priority_queue, greater<>> pq; + + dist[start] = 0; + pq.push({ 0, start }); + + while (!pq.empty()) { + int weight = pq.top().first; //간선 가중치 + int node = pq.top().second; //현재 정점 + pq.pop(); + + if (visited[node]) + continue; + + sum += weight; //MST 간선 가중치 총합 + visited[node] = true; //방문 처리 + + for (int i = 0; i < graph[node].size(); i++) { + int next_weight = graph[node][i].first; + int next_node = graph[node][i].second; + if (!visited[next_node] && next_weight < dist[next_node]) { //미방문 정점 & 더 짧은 간선 + dist[next_node] = next_weight; + pq.push({ dist[next_node], next_node }); + } + } + } + return sum; +} + +int main() { + int n, w, p; + + //입력 + cin >> n; + + vector> graph(n + 1, vector(0)); + for (int i = 1; i <= n; i++){ + cin >> w; + graph[0].emplace_back(w, i); + graph[i].emplace_back(w, 0); + } + + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + cin >> p; + if (i != j) + graph[i].emplace_back(p, j); + } + } + + + //연산 & 출력 + cout << prim(n + 1, 0, graph); +} \ No newline at end of file diff --git "a/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/16235.cpp" "b/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/16235.cpp" new file mode 100644 index 0000000..c952116 --- /dev/null +++ "b/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/16235.cpp" @@ -0,0 +1,107 @@ +#include +#include +#include + +using namespace std; + +//어디가 틀린지 모르겠다. + +int dr[] = { -1, -1, -1, 0, 0, 1, 1, 1 }; +int dc[] = { -1, 0, 1, -1, 1, -1, 0, 1 }; + +int n; +vector tree[10][10]; +vector> nutrient; //각 위치의 양분 정보 +vector> a; //겨울에 추가되는 각 위치의 양분 정보 + + + +void grow() { + //봄: 나무가 자신의 나이만큼 양분 먹기(한 칸만) -> 나이 1 증가, 어린나무부터 양분 먹음, 못 먹으면 즉시 죽음 + //여름: 죽은 나무 -> 양분, 죽은 나무의 나이를 2로 나눈 값 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (tree[i][j].size() <= 0) + continue; + + sort(tree[i][j].begin(), tree[i][j].end()); + + int summer = 0; + vector alive; + for (int k = 0; k < tree[i][j].size(); k++) { + int age = tree[i][j][k]; + if (nutrient[i][j] - age >= 0) { + nutrient[i][j] -= age; + alive.push_back(age++); + } + else { + summer += age / 2; + + } + } + nutrient[i][j] += summer; + + tree[i][j].clear(); + for (int k = 0; k < alive.size(); k++) + tree[i][j].push_back(alive[k]); + } + } + + //가을: 나무 번식, 번식 나무는 나이가 5의 배수, 인접한 8칸에 나이 1인 나무 생김. + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (tree[i][j].size() <= 0) + continue; + + for (int k = 0; k < tree[i][j].size(); k++) { + int age = tree[i][j][k]; + if (age % 5 == 0) { + for (int d = 0; d < 8; d++) { + int nr = i + dr[d], nc = j + dc[d]; + if (nr < 0 || nr >= n || nc < 0 || nc >= n) + continue; + tree[nr][nc].push_back(1); + } + } + } + } + } + //겨울: 각 칸에 양분 추가 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) + nutrient[i][j] += a[i][j]; + } +} + +int main() { + ios_base::sync_with_stdio(false); + cin.tie(NULL); + + int m, k, r, c, age; + cin >> n >> m >> k; + + nutrient.assign(n, vector(n)); + a.assign(n, vector(n)); + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + cin >> a[i][j]; + nutrient[i][j] = 5; + } + } + for (int i = 0; i < m; i++) { + cin >> r >> c >> age; + tree[r][c].push_back(age); + } + for (int i = 0; i < k; i++) { + grow(); + } + + int result = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + result += tree[i][j].size(); + } + } + cout << result; +} \ No newline at end of file diff --git "a/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1713.cpp" "b/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1713.cpp" new file mode 100644 index 0000000..dd5bf45 --- /dev/null +++ "b/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1713.cpp" @@ -0,0 +1,60 @@ +#include +#include +#include + +using namespace std; + +typedef pair ci; + +int main() { + ios_base::sync_with_stdio(false); + cin.tie(NULL); + + int n, m, candidate; + cin >> n >> m; + map photo; //{학생 번호, {추천 횟수, 게시 시간}} + int time = 0; + + while(m--) { + cin >> candidate; + //이미 게시된 학생이면 추천 횟수만 증가 + if (photo.find(candidate) != photo.end()) { + photo[candidate].first++; + } + //아니라면 + else { + //비어있는 사진틀이 없으면 + if (photo.size() >= n) { + int temp = 1001; + map::iterator erase; + + //추천수가 적은 학생 삭제 + for (auto iter = photo.begin(); iter != photo.end(); iter++) { + if (temp > iter->second.first) { + temp = iter->second.first; + erase = iter; + } + } + + //아니면 오래된 학생 삭제 + for (auto iter = photo.begin(); iter != photo.end(); iter++) { + if (temp == iter->second.first) { + if (erase->second.second > iter->second.second) + erase = iter; + } + } + photo.erase(erase); + photo.insert({ candidate, {1, time++} }); + } + + //비어있는 사진틀이 있으면 그냥 삽입 + else { + photo.insert({ candidate, {1, time++} }); + } + } + } + for (auto iter = photo.begin(); iter != photo.end(); iter++) { + cout << iter->first << " "; + } + return 0; +} \ No newline at end of file diff --git "a/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1774.cpp" "b/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1774.cpp" new file mode 100644 index 0000000..cd618c7 --- /dev/null +++ "b/11\354\233\224 30\354\235\274 - \354\265\234\354\206\214 \354\213\240\354\236\245 \355\212\270\353\246\254/1774.cpp" @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include + +using namespace std; + +//MST (크루스칼) + +typedef pair ci; +typedef tuple tp; + +vector parent; + +//Find 연산 +int findParent(int node) { + if (parent[node] < 0) //값이 음수면 루트 정점 + return node; + return parent[node] = findParent(parent[node]); //그래프 압축하며 루트 정점 찾기 +} + +//Union 연산 +bool unionInput(int x, int y) { + int xp = findParent(x); + int yp = findParent(y); + + if (xp == yp) //같은 집합에 있다면 유니온 할 수 없음 + return false; + if (parent[xp] < parent[yp]) { //새로운 루트 xp + parent[xp] += parent[yp]; + parent[yp] = xp; + } + else { //새로운 루트 yp + parent[yp] += parent[xp]; + parent[xp] = yp; + } + return true; +} + +//kruskal +double kruskal(int v, int cnt, priority_queue, greater<>> &pq) { + + double sum = 0; + + while (cnt < v - 1) { //사용한 간선의 수가 v-1보다 적을 동안 + double weight = get<0>(pq.top()); + int x = get<1>(pq.top()); + int y = get<2>(pq.top()); + pq.pop(); + + if (unionInput(x, y)) { + cnt++; + sum += weight; + } + } + return sum; +} + +int main() { + int n, m, a, b, cnt = 0; + priority_queue, greater<>> pq; + + //입력 + cin >> n >> m; + parent.assign(n, -1); + vector god(n); + for (int i = 0; i < n; i++){ + cin >> god[i].first >> god[i].second; + } + + //이미 연결된 통로 유니온 처리 + for (int i = 0; i < m; i++) { + cin >> a >> b; + if (unionInput(a - 1, b - 1)) + cnt++; + } + + //연산 + for (int i = 0; i < n - 1; i++) { + for (int j = i + 1; j < n; j++) { + double xd = god[i].first - god[j].first; + double yd = god[i].second - god[j].second; + pq.push({ sqrt(xd * xd + yd * yd), i, j }); + } + } + + //연산 & 출력 + cout << fixed; + cout.precision(2); + cout << kruskal(n, cnt, pq); +} \ No newline at end of file