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 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.

输入:

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.

输出:

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

样例输入:

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

样例输出:

Case 1: Yes
Case 2: No

题目大意:

给出一些货币和货币之间的兑换比率,问是否可以使某种货币经过一些列兑换之后,货币值增加。举例说就是1美元经过一些兑换之后,超过1美元。可以输出Yes,否则输出No。

分析:由于给出的是货币名称,所以首先我们要把货币之间的关系转化成一张图。转化时,使用的map。另外,由于Dijkstra算法不能处理带有负权值的最短路,但此题中,两种货币之间的兑换比率可能小于1,相当于这条路径的权值为负,可以使用spfa,额,因为这一题n比较小的缘故,写的时候用了floyed,毕竟需要打的比较少

code:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
using namespace std;
map<string,int> feng;
const int inf=99999999;
double a[2005][2005];
double d[2005][2005];
int n,m;
const double xiao=1e-6;
int main()
{
	int tt=1;
	while(~scanf("%d",&n))
	{
		if(n==0)break;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(i==j)a[i][j]=1;
				else a[i][j]=0;
			}
		}
		char bb[500],aa[500];
		for(int i=1;i<=n;i++)
		{
			scanf("%s",bb);
			feng[bb]=i;
		}
		scanf("%d",&m);
		for(int i=0;i<m;i++)
		{
			double much;
			scanf("%s%lf%s",aa,&much,bb);
			if(much-a[feng[aa]][feng[bb]]>1e-8)
				a[feng[aa]][feng[bb]]=much;
		} 
		for(int k=1;k<=n;k++)
		{
			for(int i=1;i<=n;i++)
			{
				for(int j=1;j<=n;j++)
				{
					a[i][j]=max(a[i][j],a[i][k]*a[k][j]);
				}
			}
		}
		double wh=a[1][1]-1.0;
		if(wh>xiao)printf("Case %d: Yes\n",tt);
		else printf("Case %d: No\n",tt);
		tt++;
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值