题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1217
题意:一种货币可以根据汇率兑换成其他货币,问是否可以通过兑换来获利例如 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.那么1 US dollar and buy 0.5 * 10.0 * 0.21 = 1.05 US dollars;就可以把1美元换成1.05美元;
如果可以获利输出Case case: Yes否则Case case: No;
思考:一共有n种货币,对于每一种货币我们可以把它对应到一个整数i上;我们可以用c++的map来处理;
map<string,int> M;
string s,t;
for (int i=1;i<=n;i++)
{
cin>>s;
M[s]=i;
}
for (int i=0;i<m;i++)
{
cin>>s>>val>>t;
f[M[s]][M[t]] = val;
}
</pre><pre>
我们可以先认为对于每一种货币 i 对于本身的汇率是1;考虑是否可以通过某一种货币 k 使得 从 i 兑换成 k ,然后再通过 k 兑换成 i;使得汇率增加;我们可以想到用floyd;只不过不是求最短路,而是求最大汇率;
<pre name="code" class="cpp">for (int k=1;k<=n;k++)
{
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
if (f[i][j] < f[i][k]*f[k][j])
f[i][j] = f[i][k]*f[k][j];
}
}
}
对于初始化的问题要放在数据处理的开头;
我们要把f[i][i]赋值为1;这个要在读数据前完成,因为数据中有这样的情况:1 US Dollar buys 2 US Dollars;一开始我就是把数据初始化放在了读入的后面,忽略了这种情况;
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
double f[50][50];
map<string,int> M;
int main()
{
int n,m,flag,cnt=1;
double val;
string s,t;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++) f[i][i]=1.0;
M.clear();
flag=0;
for(int i=1;i<=n;i++)
{
cin>>s;
M[s]=i;
}
scanf("%d",&m);
for(int i=0;i<m;i++)
{
cin>>s>>val>>t;
f[M[s]][M[t]]=val;
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(f[i][j] < f[i][k]*f[k][j])
f[i][j] = f[i][k]*f[k][j];
}
}
}
for(int i=1;i<=n;i++)
{
if(f[i][i]>1.0)
{
flag=1;
break;
}
}
if(flag==1) printf("Case %d: Yes\n",cnt++);
else printf("Case %d: No\n",cnt++);
}
return 0;
}