题目:套利是使用货币汇率的差异将一个单位的一种货币转换成多个相同的货币单位。
例如,假设1美元购买0.5英镑,1英镑购买10.0法国法郎,1法国法郎买0.21美元。然后,通过转换货币,一个聪明的商人可以从1美元买0.5 * 10.0 * 10.0 = 0.21美元,5%的盈利。
你的工作是编写一个程序,以货币汇率的列表作为输入,然后决定是否套利是可能的。
思路:采用了Floyd-Warshall算法。在这里自己对于节点如何将字符串处理成相应的数字有点麻烦,采用了通过匹配相应的字符串数组转换成数组下标。与其他的最短路径题目不同的是,本题是汇率,所以自身到自身的“路径”rate[i][i]不是为0,而是为1;还有就是如何获利,当运算后的“路径”(rate[i][i])>1 也就能获利了。而且最短路径的递增公式也从“+”变成了“”rate[i][j]= rate[i][k] rate[k][j];
import java.util.Scanner;
public class Arbitrage {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int count=0;
while (true) {
count++;
n=in.nextInt();
if (n==0) {
break;
}
curr=new String[n];
rate=new double[n][n];
for (int i = 0; i < n; i++) {
rate[i][i]=1;
}
for (int i = 0; i < curr.length; i++) {
curr[i]=in.next();
}
m=in.nextInt();
for (int i = 0; i < m; i++) {
int f=strToin(in.next());
double c=Double.parseDouble(in.next());
int t=strToin(in.next());
rate[f][t]=c;
}
if (Floyd()) {
System.out.println("Case "+count+": Yes");
}else {
System.out.println("Case "+count+": No");
}
}
// TODO Auto-generated method stub
}
final static int INF=9999;
static double rate[][];
static int n;
static int m;
static String[] curr;
public static boolean Floyd(){
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (rate[i][j] < rate[i][k] * rate[k][j]) {
rate[i][j]= rate[i][k] * rate[k][j];
}
}
}
}
for (int i = 0; i < n; i++) {
if (rate[i][i]> 1) {
return true;
}
}
return false;
}
public static int strToin(String str){
for (int i = 0; i < curr.length; i++) {
if (str.equalsIgnoreCase(curr[i])) {
return i;
}
}
return -1;
}
}