题目描述
套利是利用货币汇率差异将一种货币单位转换成一种以上相同货币单位。例如,假设1美元买入0.5英镑,1英镑买入10.0法国法郎,1法国法郎买入0.21美元。然后,通过转换货币,聪明的交易者可以从1美元开始,买入0.5 * 10.0 * 0.21 = 1.05美元,获利5%。
您的工作是编写一个程序,该程序将货币汇率列表作为输入,然后确定是否可以进行套利。
输入
第一行中,有一个整数n(1 <= n <= 30),代表不同货币的数量。
接下来的n行分别包含一种货币的名称。名称中不会出现空格(货币名称可能会重复)
下一行包含一个整数m,代表要遵循的表的长度。最后m行分别包含源货币的名称ci,
代表ci到cj的汇率的实数rij和目标货币的名称cj。没有出现在表中的交换是不可能的
(可能存在同币种不同汇率情况,保留汇率高的情况)
输出
yes或no的格式打印一行,说明是否可以套利。
样例输入
3
USDollar
BritishPound
FrenchFranc
3
USDollar 0.5 BritishPound
BritishPound 10.0 FrenchFranc
FrenchFranc 0.21 USDollar
样例输出
yes
提示;弗洛伊德+map映射
#include<bits/stdc++.h>
#define quickly() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define P 50
#define bet(n,x,y,u) n[x][y]=n[y][x]=u
using namespace std;
int n,m;
bool flag=false;
double profit[P][P],rate;
map<string,int> conversion;
string s1,s2;
void floyd(){
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
profit[i][j]=max(profit[i][j],profit[i][k]*profit[k][j]);
}
int main(){
quickly();
cin>>n;
conversion.clear();
for(int i=1;i<=n;i++){
cin>>s1;
conversion[s1]=i;
}cin>>m;
for(int i=1;i<=m;i++){
cin>>s1>>rate>>s2;
profit[conversion[s1]][conversion[s2]]=rate;
}floyd();
for(int i=1;i<=n;i++){
if(profit[i][i]>1){
flag=true;
break;
}
}if(flag)cout<<"yes";
else cout<<"no";
}