※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 6598번 문제인 Arbitrage이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/6598 

 

6598번: Arbitrage

Arbitrage is the use of discrepancies in currency exchange rates to transform one unit of a currency into more than one unit of the same currency. For example, suppose that 1 US Dollar buys 0.5 British pound, 1 British pound buys 10.0 French francs, and 1

www.acmicpc.net

문제의 상황을 각 화폐를 노드로, 환전 비율을 가중치를 갖는 에지로 모델링할 수 있다. 이 때, 한 화폐에서 출발하여 자기 자신으로 돌아오는, 모든 에지의 가중치를 곱했을 때의 값이 1을 넘는 사이클이 존재하는지를 판단하는 것으로 문제를 해결할 수 있다.

 

문제에서 주어지는 N의 값이 충분히 작으므로, 위와 같은 사이클이 존재하는지의 여부는 Floyd-Warshall 알고리즘과 같은 형태의 DP를 이용하여 쉽게 판별할 수 있다.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <string>
#include <map>
using namespace std;

int N, M;
map<string, int> mp;

long double dist[31][31];
int casenum = 0;

void solve() {
	casenum++;
	mp.clear();
	for (int r = 1; r <= N; r++) {
		for (int c = 1; c <= N; c++) {
			dist[r][c] = 0;
		}
	}

	for (int i = 1; i <= N; i++) {
		string s; cin >> s;
		mp.insert(make_pair(s, i));
	}
	cin >> M;
	while (M--) {
		string s1, s2; long double r; cin >> s1 >> r >> s2;
		dist[mp[s1]][mp[s2]] = r;
	}
	
	for (int k = 1; k <= N; k++) {
		for (int r = 1; r <= N; r++) {
			for (int c = 1; c <= N; c++) {
				dist[r][c] = max(dist[r][c], dist[r][k] * dist[k][c]);
			}
		}
	}

	bool chk = 0;
	for (int i = 1; i <= N; i++) {
		if (dist[i][i] > 1) chk = 1;
	}

	if (chk) cout << "Case " << casenum << ": Yes\n";
	else cout << "Case " << casenum << ": No\n";
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N;
	while (N) {
		solve();
		cin >> N;
	}
}
728x90

+ Recent posts