博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Arbitrage
阅读量:2038 次
发布时间:2019-04-28

本文共 5743 字,大约阅读时间需要 19 分钟。

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 French franc buys 0.21 US dollar. Then, by converting currencies, a clever trader can start with 1 US dollar and buy 0.5 * 10.0 * 0.21 = 1.05 US dollars, making a profit of 5 percent. 

Your job is to write a program that takes a list of currency exchange rates as input and then determines whether arbitrage is possible or not. 

Input

The input file will contain one or more test cases. Om the first line of each test case there is an integer n (1<=n<=30), representing the number of different currencies. The next n lines each contain the name of one currency. Within a name no spaces will appear. The next line contains one integer m, representing the length of the table to follow. The last m lines each contain the name ci of a source currency, a real number rij which represents the exchange rate from ci to cj and a name cj of the destination currency. Exchanges which do not appear in the table are impossible.

Test cases are separated from each other by a blank line. Input is terminated by a value of zero (0) for n. 

Output

For each test case, print one line telling whether arbitrage is possible or not in the format "Case case: Yes" respectively "Case case: No". 

Sample Input

3USDollarBritishPoundFrenchFranc3USDollar 0.5 BritishPoundBritishPound 10.0 FrenchFrancFrenchFranc 0.21 USDollar3USDollarBritishPoundFrenchFranc6USDollar 0.5 BritishPoundUSDollar 4.9 FrenchFrancBritishPound 10.0 FrenchFrancBritishPound 1.99 USDollarFrenchFranc 0.09 BritishPoundFrenchFranc 0.19 USDollar0

Sample Output

Case 1: YesCase 2: No

题意:

已知n种货币,以及m种货币汇率及方式,问能否通过货币转换,使得财富增加。

解题思路:

目测是一条不错的生财之道~~~(打住)

财富增加的话肯定是以同种货币作比较,否则没有意义,因此题意大致可以变成在一个n个顶点的图中能否找到一个正权环,这里的正权环指财富增加,很明显可用Bellman-ford 算法(专门解决存在环的最短路径问题)。

Bellman-ford 算法:一个具有n个顶点的图如果不存在环,则从顶点x,到顶点y,最多经过n-1条边(要考虑连通性,每个顶点最多经过 1 次),因此 x 到 y 的最短路 最多经过 n - 1 次松弛操作(就是更新长度)就应该出现,如果第 n 次松弛还可以得到最优,那么这个图就肯定是存在环了(直接用Dijkstra 就无法得到最优的,环的存在会影响最优解是否存在)。

这里给的顶点时货币的英文名,为了方便简洁,用map 将货币名 与 编号一一对应

此题有多种解法,注意到顶点最大为30(限制很小,不愧是模板练习题),可用Floyd算法求出整个图的最短路,注意此处并不是真正的最短路,但通过插点,即 i -> j 能否改成 i -> k -> j 的路,就会把环给考虑至少一次,那么对应的 path[i][i] 也就是本金肯定是增加的(相对于初值),为了方便,将本金设为 1 .

C++版本一

Bellman_ford

#include 
#include
#include
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3fusing namespace std;int t,n,m;map
m0;double r;double dist[200];struct node{ int a,b; double r; node(int sst,int eed,double rtt) : a(sst),b(eed),r(rtt) {} node() {}};vector
G;bool Bellman_ford(int v){ memset(dist,0,sizeof(dist)); dist[v] = 1; for(int j = 1;j < n;j++) { // n - 1 次松弛操作 for(int i = 0;i
< G.size();i++){ int p1 = G[i].a,p2 = G[i].b; if(dist[p2] < dist[p1] * G[i].r) { //第 n 次松弛可以得到更优解,则存在环 return true; } } return false;}int main(){ t=0; while(~scanf("%d",&n)){ if(n==0) break; t++; char tempchar1[100],tempchar2[100]; for(int i=0;i

C++版本二

Floyd 

//floyed#include
#include
#include
#include
#include
#include
#include
using namespace std;int n,m;double dist[40][40];map
money; void init(){ for(int i = 0;i < n;i++) { for(int j = 0;j < n;j++){ if(i == j) dist[i][j] = 1; else dist[i][j] = 0; } }} void floyd(){ for(int k = 0;k < n;k++) { for(int i = 0;i < n;i++) { for(int j = 0;j < n;j++) { if(dist[i][j] < dist[i][k] * dist[k][j]) dist[i][j] = dist[i][k] * dist[k][j]; } } }} int main(){ int cas = 1; string s,ss; double r; while(~scanf("%d",&n) &&n) { init(); for(int i = 0;i < n;i++) { cin >> s; money[s] = i; } cin >> m; for(int i = 0;i < m;i++) { cin >> s >> r >> ss; dist[money[s] ][money[ss] ] = r; } floyd(); printf("Case %d: ",cas++); for(int i = 0;i < n;i++) { if(dist[i][i] > 1) { cout << "Yes" << endl; break; } else if(i == n - 1) cout << "No" <

C++版本三 

Floyd 

#include 
#include
#include
#include
using namespace std; int main(){ double e[35][35]; int n; map
exchange_rate;int num=0; while (cin>>n&&n!=0) { memset(e,0,sizeof(e)); for(int i=1; i<=n; i++) e[i][i]=1; num++; int p=1; string currency ; for(int i=0; i
>currency; exchange_rate.insert(make_pair(currency,p++)); } int m; cin >>m; for(int i=0; i
>a>>b>>c; e[exchange_rate[a]][exchange_rate[c]]=b; } for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(e[i][j]
1) { cis++; } if(cis==0) cout <<"Case "<
<<": No"<

C++版本四

SPFA

#include
using namespace std;#include
#include
#include
#define maxn 0x7fffffff#include
int n,m,f;double dis[3000];int vis[3000],head[3000];struct node{ double w; int e,next;}edge[3000];void add(int s,int e,double w){ edge[f].e=e; edge[f].w=w; edge[f].next=head[s]; head[s]=f++;}int spfa(int s){ int cur,k,i; queue
q; while(!q.empty()) { q.pop(); } q.push(s); dis[s]=1; vis[s]=1; while(!q.empty()) { cur=q.front(); q.pop(); vis[cur]=0; for(i=head[cur];i!=-1;i=edge[i].next) { k=edge[i].e; if(dis[k]
1) return 1; } } return 0;}int main(){ int i,j=1; double w; char s[100],s1[100],s2[100]; map
v; while(cin>>n) { if(n==0)break; f=0; memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); for(i=0;i<100;i++) dis[i]=0; for(i=1;i<=n;i++) { cin>>s; v[s]=i; } cin>>m; for(i=0;i
>s1>>w>>s2; add(v[s1],v[s2],w); } cout<<"Case "<
<<": "; for(i=1;i<=n;i++) { if(spfa(i)) { cout<<"Yes\n"; break; } } if(i==n+1) cout<<"No\n"; j++; } return 0;}

 

转载地址:http://tewof.baihongyu.com/

你可能感兴趣的文章
Go语言学习Part1:包、变量和函数
查看>>
Go语言学习Part2:流程控制语句:for、if、else、switch 和 defer
查看>>
Go语言学习Part3:struct、slice和映射
查看>>
Go语言学习Part4-1:方法和接口
查看>>
Leetcode Go 《精选TOP面试题》20200628 69.x的平方根
查看>>
Leetcode C++ 剑指 Offer 09. 用两个栈实现队列
查看>>
Leetcode C++《每日一题》20200707 112. 路径总和
查看>>
Leetcode C++ 《第198场周赛-2》 1519. 子树中标签相同的节点数
查看>>
Leetcode C++ 《第199场周赛》
查看>>
Leetcode C++ 《第200场周赛》
查看>>
Leetcode C++ 《第201场周赛》
查看>>
云原生 第十章 应用存储和持久化数据卷:存储快照和拓扑调度
查看>>
云原生 第十一章 应用健康
查看>>
Leetcode C++ 《第202场周赛》
查看>>
云原生 第十二章 可观测性:监控与日志
查看>>
Leetcode C++ 《第203场周赛》
查看>>
云原生 第十三章 Kubernetes网络概念及策略控制
查看>>
《redis设计与实现》 第一部分:数据结构与对象 || 读书笔记
查看>>
《redis设计与实现》 第二部分(第9-11章):单机数据库的实现
查看>>
Leetcode C++《热题 Hot 100-70》23.合并K个升序链表
查看>>