Arbitrage
| Time Limit: 1000MS | Memory Limit: 65536K | |
|---|---|---|
| Total Submissions: 17691 | Accepted: 7467 |
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. \
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.
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
\
\
\
套汇问题。。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
char s[16];
int num;
} qu[1000];
struct no//注意q[]的数组应该开大点,最环的情况为n*n
{
int a,b;
double r;
} q[1000];
char s1[16],s2[16];
double rate;
int sum,n,m;
double dis[1000000];
bool bf()
{
int i,j;
memset(dis,0,sizeof(dis));
dis[1]= 1 ;//一般题目没有名白的说从哪里开始,墨认为1
for(i=1; i<n; i++)
for(j=0; j<sum; j++)
if(dis[q[j].b ]<dis[ q[j].a ]*q[j].r )
dis[q[j].b ]=dis[ q[j].a ]*q[j].r;
for(j=0; j<sum; j++)//一定注意再判断正环时,只在q[]自己的范围内,而不是
if(dis[q[j].b ]<dis[ q[j].a ]*q[j].r)
{
return true ;
}
return false;
}
int cla=1;
int main()
{
ios::sync_with_stdio(false);
while(scanf("%d",&n)&&n)
{
sum=0;
for(int i=1; i<=n; i++)
{
scanf("%s",qu[i].s);
qu[i].num=i;
}
scanf("%d",&m);
while(m--)
{
int a=0,b=0;
scanf("%s%lf%s",s1,&rate,s2);
for(int j=1; j<=n; j++)
{
if( ! strcmp(s1,qu[j].s) )
a=qu[j].num;
if( !strcmp(s2,qu[j].s) )
b=qu[j].num;
if(a!=0&&b!=0)
break;
}
q[sum].a=a;
q[sum].b=b;
q[sum++].r=rate;
}
bool o=bf();
printf("Case %d: ",cla++);
if(o==true)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
\
\
\
SPFA:
#include<map>
#include<queue>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
char s[1000],s1[1000];
double Map[100][100],dis[100];
int m,n,tmp[100],sum;
bool vis[100];
bool spfa(){
for(int i=0;i<=n;i++){
dis[i]=0;
vis[i]=false;
tmp[i]=0;
}
dis[1]=1;
vis[1]=true;
queue<int>q;while(!q.empty())q.pop();
q.push(1);
while(!q.empty()){
int u=q.front();q.pop();
tmp[u]++;
if(tmp[u]>n) return false;
vis[u]=false;
for(int i=1;i<=n;i++){
if( (dis[i]<dis[u]*Map[u][i])&&Map[u][i]){
dis[i]=dis[u]*Map[u][i];
if(!vis[i]){
vis[i]=true;
q.push(i);
}
}
}
}
return true;
}
int main(){
int i,j,k,cnt=1;
while(~scanf("%d",&n)&&n){
sum=0;
map<string,int>mp;
mp.clear();
for(i=1;i<=n;i++){
scanf("%s",s);
mp[s]=i;
}
for(i=0;i<100;i++){
for(j=0;j<100;j++){
Map[i][j]=0;
}
}
scanf("%d",&m);
double p;
for(i=1;i<=m;i++){
scanf("%s %lf %s",s,&p,s1);
Map[mp[s]][mp[s1]]=p;
}
bool o=spfa();
printf("Case %d: ",cnt++);
if(!o){
puts("Yes");
}
else
puts("No");
}
return 0;
}
\