(2020년 12월 21일에 작성한 글입니다.)
Dashboard - Codeforces Round #692 (Div. 2, based on Technocup 2021 Elimination Round 3) - Codeforces
codeforces.com


A.
그냥 구현.
string 입력받고 뒤에서부터 세주면 된다
int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int T;
	int N;
	string s;
	int i;
	int cnt;
	cin >> T;
	while (T--) {
		cin >> N;
		cin >> s;
		cnt = 0;
		for (i = N - 1; i >= 0; i--) {
			if (s[i] == ')') {
				cnt++;
			}
			else {
				break;
			}
		}
		if (cnt > N - cnt) {
			cout << "Yes" << '\n';
		}
		else {
			cout << "No" << '\n';
		}
	}
	return 0;
}
B.
와 진짜 멘붕 왔다.
근데 효규가 이걸 7분만에 풀어서 당황했는데
그냥 N부터 1씩 증가해나가면서 확인하는 게 답이다..
int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int T;
	int N;
	string s;
	int i;
	int cnt;
	cin >> T;
	while (T--) {
		cin >> N;
		cin >> s;
		cnt = 0;
		for (i = N - 1; i >= 0; i--) {
			if (s[i] == ')') {
				cnt++;
			}
			else {
				break;
			}
		}
		if (cnt > N - cnt) {
			cout << "Yes" << '\n';
		}
		else {
			cout << "No" << '\n';
		}
	}
	return 0;
}
C.
그리고 또 멘붕.
처음에는, 빈 공간이 있는지 찾고
빈 공간으로 가면 되는 걸 보내고
그걸 계속 반복하는 방법으로 풀었는데
TLE가 났다.
결국 이 문제는
X를 Y로 보낼 때 몇 번 이동시켜야 하는지 보는거니까
방향그래프로 나타낼 수 있고,
그렇게 나타낸 그래프는 특이하게도 모든 노드가 들어오는 간선, 나가는 간선이 최대 하나만 존재한다.
만약 사이클이 없으면 그냥 차례대로 다 옮겨주면 되기 때문에
옮기는 횟수는 (노드 수) - 1로 하면 되고
사이클이 있으면 그 중 하나를 다른 곳으로 일단 보내고, 차례대로 이동시켜야 한다.
그래서 옮기는 횟수는 (노드 수) + 1.
이 문제의 그래프에서는 사이클에서 노드 수 == 간선 수니까
정확하게 말하면 옮기는 횟수가 (간선 수) + 1인데
(노드 수) + 1로 구하면 된다.
그럼 이걸 어떻게 하느냐!!
Union-Find로 하면 된다
merge할 때, 둘 중 번호가 작은 것을 대표 노드로 업데이트 하고
cnt도 처리해줬다.
그리고 유의할 점은
input으로 X, Y 받을 때
X == Y 이면 continue 하는거 놓치면 안 된다.
여기서 처리 안 하면, 그 뒤에서 복잡해진다...ㅎ
vector<int> par;
vector<int> cnt;
int getPar(int);
void merge(int, int);
int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int T;
	int N, M;
	int X, Y;
	int ans;
	int i;
	cin >> T;
	while (T--) {
		cin >> N >> M;
		par.clear();
		par.resize(N + 5, -1);
		cnt.clear();
		cnt.resize(N + 5, 1);
		set<int> nums;
		ans = 0;
		while (M--) {
			cin >> X >> Y;
			if (X == Y) {
				continue;
			}
			nums.insert(X);
			nums.insert(Y);
			if (getPar(X) == getPar(Y)) {
				ans += cnt[getPar(X)] + 1;
				cnt[getPar(X)] = 0;
			}
			else {
				merge(X, Y);
			}
		}
		for (auto iter = nums.begin(); iter != nums.end(); iter++) {
			i = *iter;
			int temp = getPar(i);
			if (cnt[temp]) {
				ans += cnt[temp] - 1;
				cnt[temp] = 0;
			}
		}
		cout << ans << '\n';
	}
	return 0;
}
int getPar(int x)
{
	if (par[x] == -1) {
		return x;
	}
	return par[x] = getPar(par[x]);
}
void merge(int a, int b)
{
	a = getPar(a);
	b = getPar(b);
	if (a > b) {
		swap(a, b);
	}
	if (a != b) {
		cnt[a] += cnt[b];
		cnt[b] = 0;
		par[b] = a;
	}
}