N의 입력 범위가 작기 때문에, 소를 계속 가능한 위치에 이동시켜주면서 풀어 나가면 됩니다.
또한, 네트워크 플로우의 특성인 어느 소부터 시작하던지, 결국 되는경우는 모두 처리가 되기 때문에,
1번 소부터 N번 소까지 차레대로 처리해주면 됩니다.
k번 소를 원하는 지역에 넣으려고 하는 경우 두가지 케이스가 있습니다
case 1 ) 해당 지역이 비어있는 경우
case 2 ) 다른소가 차지하고 있는 경우
< case 1 >
해당 지역에 k번째 소를 넣어주고
k번째 소가 어느위치에 있는지도 알고 있어야 합니다.
< case 2 >
해당 지역에 있는 소를 y소라고 한다면,
y소를 다른위치로 옮겨야 합니다.
재귀 함수를 사용해서, y소를 다른 지역에 옮길 수 있는지 확인한뒤
(옮긴 후) k번째 소를 해당 지역에 넣어 주면 됩니다.
전체코드
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define endl '\n'
//--------------------------------------------------------------------------------------
#define MAX_N 201
vector<int> map[MAX_N];
int cow[MAX_N];
int area[MAX_N];
bool visit[MAX_N];
bool fun(int s) {
// s번 소는 방문
visit[s] = true;
for (int i = 0; i < map[s].size(); i++) {
// 해당 지역이 비었거나
// 그렇지 않다면
// 현재 가려고 하는 위치의 소가 처리 되있지 않고
// &&
// 처리 되지 않은소가 다른 지역으로 옮겨갔다면 ( true가 return 된다 )
if (area[map[s][i]] == -1 || (!visit[area[map[s][i]]] && fun(area[map[s][i]]))) {
cow[s] = map[s][i];
area[map[s][i]] = s;
return true;
}
}
// 소를 현재 위치에서 이사시킬 수 없는 경우
return false;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int N, M; cin >> N >> M;
for (int i = 1; i <= N; i++) {
int s; cin >> s;
for (int j = 0; j < s; j++) {
int data; cin >> data;
map[i].push_back(data);
}
}
memset(cow, -1, sizeof(cow));
memset(area, -1, sizeof(area));
int ans = 0;
for (int i = 1; i <= N; i++) {
// 1번 소 부터 차례대로 넣는다 ( 플로우 형식이기 때문에 그냥 차례대로 확인해도 상관없다 )
if (cow[i] == -1) {
memset(visit, false, sizeof(visit));
if (fun(i)) ans++;
}
}
cout << ans << endl;
}
// 이름의 길이에 등수를 push_back
for (int i = 0; i < N; i++) {
string input; cin >> input;
vec[input.size()].push_back(i + 1);
}
입력이 문자열로 들어오지만, 저희가 필요한 정보는 문자열의 길이와 등수뿐 입니다.
<정렬>
이문제의 핵심이라고 할 수 있는 부분입니다.
이름 길이가 같은 친구끼리 묶인 vector에서 정렬을 통해서
이후에, 선형 조사를 하게 되던, lower_bound, upper_bound를 하게되던 정렬을 해야만
큰 입력에 대해서 시간안에 답을 구할 수 있습니다.
// i 길이의 이름을 가진 친구들을 등수별로 sort
for (int i = 0; i < 21; i++) {
sort(vec[i].begin(), vec[i].end());
}
<upper_bound>
i 길이의 이름을 가진 친구중에서 j번째 등수기준으로
j + K 번째 등수까지 몇명이 있는지 알기위해서
이분탐색을통해서 알 수 있습니다.
for (int i = 0; i < 21; i++) {
// upper_bound를 편의를 위한 push_back
vec[i].push_back(1e9);
for (int j = 0; j < vec[i].size()-1; j++) {
// 자신의 등수보다 K 보다 큰 마지막 친구가 iter로 반환 됩니다.
auto iter = upper_bound(vec[i].begin(), vec[i].end(), vec[i][j] + K); iter--;
// 시작 주소를 빼줌으로써 index값을 얻을 수 있고
auto index = iter - vec[i].begin();
// 마지막 친구의 index - 현재 index를 해주면 친구의 명수가 나오게 됩니다.
ans += index - j;
}
}
전체코드
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <string>
using namespace std;
vector<int> vec[21];
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int N, K; cin >> N >> K;
// 이름의 길이에 등수를 push_back
for (int i = 0; i < N; i++) {
string input; cin >> input;
vec[input.size()].push_back(i + 1);
}
// i 길이의 이름을 가진 친구들을 등수별로 sort
for (int i = 0; i < 21; i++) {
sort(vec[i].begin(), vec[i].end());
}
long long ans = 0;
for (int i = 0; i < 21; i++) {
// upper_bound를 편의를 위한 push_back
vec[i].push_back(1e9);
for (int j = 0; j < vec[i].size()-1; j++) {
// 자신의 등수보다 K 보다 큰 마지막 친구가 iter로 반환 됩니다.
auto iter = upper_bound(vec[i].begin(), vec[i].end(), vec[i][j] + K); iter--;
// 시작 주소를 빼줌으로써 index값을 얻을 수 있고
auto index = iter - vec[i].begin();
// 마지막 친구의 index - 현재 index를 해주면 친구의 명수가 나오게 됩니다.
ans += index - j;
}
}
cout << ans << "\n";
}
저는 x축 을 기준으로 정렬한뒤에 현재까지 선을 그은 마지막 위치를 저장하여 처리 했습니다.
전체코드
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <string>
using namespace std;
typedef pair<int, int> pii;
vector<pii> vec;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int N; cin >> N;
for (int i = 0; i < N; i++) {
int a, b; cin >> a >> b;
if (b < a) {
int t = b;
b = a;
a = t;
}
vec.push_back({ a,b });
}
int e = -(1e9+1);
int ans = 0;
sort(vec.begin(), vec.end());
for (int i = 0; i < N; i++) {
if (e == -(1e9 + 1)) {
e = vec[i].second;
ans += e - vec[i].first;
}
if (vec[i].first < e) {
int diff = vec[i].second - e;
ans += (diff > 0) ? diff : 0;
e = max(e,vec[i].second);
}
else if (vec[i].first >= e) {
ans += vec[i].second - vec[i].first;
e = vec[i].second;
}
}
cout << ans << "\n";
}