Arbitrage
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 20575 | Accepted: 8768 |
Description
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.
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 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.
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
3 USDollar BritishPound FrenchFranc 3 USDollar 0.5 BritishPound BritishPound 10.0 FrenchFranc FrenchFranc 0.21 USDollar 3 USDollar BritishPound FrenchFranc 6 USDollar 0.5 BritishPound USDollar 4.9 FrenchFranc BritishPound 10.0 FrenchFranc BritishPound 1.99 USDollar FrenchFranc 0.09 BritishPound FrenchFranc 0.19 USDollar 0
Sample Output
Case 1: Yes Case 2: No
题意:给你一些货币比如A,B,C,然后给你他们之间存在的对换关系,如A可以换0.5个B,B可以换10个C,C可以换2个A等.然后问你是否存在一种对换可以使得1个A可以换到大于1个A的钱.
分析:
首先把每个货币的单词映射成一个数字,表示该货币的编号.然后其实本题用到了类似Floyd的动态规划思想.
首先假设货币1对换货币2 比率为a,货币2对换货币3 比率为b.
那么货币1对换货币3比率为多少呢?
为a*b.
现在我们希望货币能增值,所以如果货币1换货币3 有两种比率分别为0,5和0,6.那么我们明显放弃0.5那个,只需要用0.6的比率即可.所以这道题就成了求一个有向图的任意两点的最大兑换比例,不过这个比例不是相加运算了,而是相乘运算.
且现在不是最小值最优了,而是最大值最优了. 其实原理就是Floyd的动态规划原理.其实就是传递闭包,证明省略,可以参考Floyd的证明过程.
#include <iostream> #include <map> using namespace std; const int maxn = 35; const int INF = 0x3ffffff; map<string,int> Map; double e[maxn][maxn]; int main(){ string s1,s2; int i ,j , k; double rate; int cases = 1; int n,m; while(cin>>n&&n){ int cnt = 0; //初始化权值,乘以本身的利率是1 for(i = 0;i<n;i++){ for(j=0;j<n;j++){ if(i==j) e[i][j]=1; else e[i][j]=-INF; } } for(i=0;i<n;i++){ cin>>s1; Map[s1] = cnt;//初始化点的编号 cnt++; } cin>>m; for(i=0;i<m;i++){ cin>>s1>>rate>>s2; e[Map[s1]][Map[s2]]=rate; } //Floyd思想 for(k=0;k<n;k++) for(i=0;i<n;i++) for(j=0;j<n;j++) if(e[i][j]<e[i][k]*e[k][j]) //初始化e为-INF的原因,方便取最大值 e[i][j]=e[i][k]*e[k][j]; int flag = 0; //遍历所有本钱 for(i=0;i<n;i++){ if(e[i][i]>1) flag=1; } if(flag) cout<<"Case "<<cases<<": Yes"<<endl; else cout<<"Case "<<cases<<": No"<<endl; cases++; } return 0; }