순간을 성실히, 화려함보단 꾸준함을

Codeforces Raif Round 1 (Div. 1 + Div. 2) : B번 본문

알고리즘,SQL/codeforce 문제

Codeforces Raif Round 1 (Div. 1 + Div. 2) : B번

폭발토끼 2020. 10. 21. 09:37

codeforces.com/contest/1428/problem/B

 

Problem - B - Codeforces

 

codeforces.com

문제 : n개의 간선의 정보가 주어진다.

- : 양옆으로 갈 수 있는 간선

> : i 에서 (i+1)%n 으로 갈 수 있는 간선

< : (i+1)%n 에서 i 로 갈 수 있는 간선

이때, 각 정점에서 출발하여 다시 자기 자신으로 돌아올 수 있는 정점의 개수를 구하면 된다.

 

해설 : 크게 2가지 케이스가 존재한다.

1) 현재 정점에서 나간 방향으로 시작하여 그대로 한바퀴 돌아서 돌아오는 경우

2) 그렇지 않고 나간 방향의 역방향으로 다시 들어오는 경우

 

첫번째 케이스는 한바퀴를 돌아야 함으로, (-,>) 만으로 이루어져 있거나 (-,<) 만으로 이루어져 있으면 된다. 이는 곧 돌아올 수 있는 정점의 개수는 n 개가 된다.

두번째 케이스는 나갔다가 다시 돌아오는 경우이니 현재 정점에서 양옆들 중 하나만이라도 - 이면 된다.

 

#include<bits/stdc++.h>
 
using namespace std;
using ll = long long;
 
void solve();
 
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
 
	int t = 0;
	cin >> t;
	while (t--) 
		solve();	
	return 0;
}
void solve()
{
	int n;
	string s;
	vector<int> v[3];
	cin >> n >> s;
	for (int i = 0; i < s.length(); i++)
	{
		if (s[i] == '-')v[0].push_back(i);
		if (s[i] == '>')v[1].push_back(i);
		if (s[i] == '<')v[2].push_back(i);
	}
	int ans = 0;
	if (v[0].size() + v[1].size() == n || v[0].size() + v[2].size() == n)
		cout << n << "\n";
	else {
		for (int i = 1; i <= n; i++)
		{
			int l = i - 1;
			int r = i % n;
 
			if (s[l] == '-' || s[r] == '-')
				ans++;
		}
		cout << ans << "\n";
	}
	return;
}