이 문제는 폭이 1인 강이면 구할 수 있겠는데 2 * 2처럼 통통한? 강이면 어떻게 강 면적을 셀 수 있는지 모르겠다..
DFS 처럼 트리로 만든 다름 총 몇 개의 트리가 있는지 세면 되지 않을까? 라는 생각이 잠시 스치긴 했는데
이걸 노드로 어떻게 연결할지 모르겠고 아닌 것 같아서 패스했다.
---
인간아 트리 아니고 그래프!
암튼.. 못 풀어서 북님한테 힌트 들었다.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <string>
#include <queue>
#include <stack>
#include <set>
using namespace std;
using i64 = long long;
using ii = pair<int, int>;
bool visited[55][55];
char map[55][55];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
int n, m;
bool sort_by_size(const vector<ii> &a, const vector<ii> &b)
{
return (a.size() < b.size());
}
void dfs(int x, int y, vector<ii> &v)
{
if (visited[x][y])
return ;
if (map[x][y] == '*')
return ;
visited[x][y] = true;
v.emplace_back(x, y);
for (int i = 0; i < 4; i++)
{
if (x + dx[i] >= 0 && y + dy[i] >= 0 && y + dy[i] < m && x + dx[i] < n)
dfs(x + dx[i], y + dy[i], v);
}
}
void print_map(int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
printf("%c", map[i][j]);
}
printf("\n");
}
}
bool check_river(vector<ii> &element)
{
for (int i = 0; i < element.size(); i++)
{
if (element[i].first == 0 || element[i].first == n-1)
return false;
if (element[i].second == 0 || element[i].second == m-1)
return false;
}
return true;
}
int main()
{
int k;
scanf("%d %d %d", &n, &m, &k);
char tmp;
scanf("%c", &tmp);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
scanf("%c", &map[i][j]);
}
scanf("%c", &tmp);
}
vector<ii> ans[2500];
int count = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (map[i][j] == '.' && !visited[i][j])
{
vector<ii> element;
dfs(i, j, element);
if (check_river(element))
ans[count++] = element;
}
}
}
sort(&ans[0], &ans[count], sort_by_size);
// for (int i = 0; i < count; i++)
// {
// for (int j = 0; j < ans[i].size(); j++)
// {
// cout << ans[i][j].first << ", " << ans[i][j].second << endl;
// }
// cout << endl;
// }
int min_num = 0;
for (int i = 0; i < count - k; i++)
{
min_num += ans[i].size();
//cout << min_num << endl;
}
//cout << count << endl;
cout << min_num << endl;
for (int i = 0; i < count - k; i++)
{
for (int j = 0; j < ans[i].size(); j++)
{
map[ans[i][j].first][ans[i][j].second] = '*';
}
}
print_map(n, m);
return 0;
}
짜면서 재미는 있었는데 어렵다,, 쉬운 1600점이라니 믿을 수 없다
이젠 dfs 어떻게 동작하는지 살짝 알 것 같기도 하고
좀 더 연습해야 할듯
'코드포스' 카테고리의 다른 글
[코드포스 Practice19] A. Ternary XOR (0) | 2020.05.15 |
---|---|
[코드포스 Practice19] 후기 (0) | 2020.05.15 |
[코드포스 Practice18] D. Mr. Kitayuta's Colorful Graph (0) | 2020.04.16 |
[코드포스 Practice18] C. Vanya and Exams (0) | 2020.04.16 |
[코드포스 Practice18] B. Dreamoon and WiFi (0) | 2020.04.16 |