算法设计与分析: 4-15 套汇问题

这篇博客探讨了套汇问题,即如何利用不同货币间的汇率差异获取利润。通过介绍一个商人从1美元出发,经过多次兑换最终获得超过1美元的例子,说明了套汇的原理。文章提供了算法设计思路,针对给定的多种货币及其兑换率,判断是否存在套汇的可能性。内容包括问题描述、Java实现以及输入输出示例。

4-15 套汇问题


问题描述

套汇是指利用货币汇兑率的差异将一个单位的某种货币转换为大于一个单位的同种货 币。例如,假定 1 美元可以买 0.7 英镑,1 英镑可以买 9.5 法郎,且 1 法郎可以买到 0.16 美元。通过货币兑换,一个商人可以从 1 美元开始买入,得到 0.7×9.5×0.16=1.064 美元, 从而获得 6.4%的利润。

给定 n 种货币c1,c2,...,cnc1,c2,...,cn 的有关兑换率,试设计一个有效算法,用以确定是否存在套汇的可能性。

含多个测试数据项。每个测试数据项的第一行中只 有 1 个整数 n (1<=n<=30),表示货币总数。其后 n 行给出 n 种货币的名称。接下来的一行中 有 1 个整数 m,表示有 m 种不同的货币兑换率。其后 m 行给出 m 种不同的货币兑换率,每 行有 3 个数据项 cicirijrijcjcj ,表示货币 cicicjcj 的兑换率为rijrij


Java

import java.util.Scanner;

public class TaoHui {

    private static int n,edges;
    private static String[] name;
    private static double[][] r;
    private static String a,b;
    private static double x;
    private static int cases = 0;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while (true){
            cases++;
            int i,j,k;
            n = input.nextInt();

            name = new String[n];
            r = new double[n][n];

            if(n == 0) break;
            for(i=0; i<n; i++)
                name[i] = input.next();

            for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                    r[i][j] = 0.0;

            edges = input.nextInt();
            for(i=0; i<edges; i++){
                a = input.next();
                x = input.nextDouble();
                b = input.next();
                for(j=0; !a.equals(name[j]); j++);
                for(k=0; !b.equals(name[k]); k++);
                r[j][k] = x;
            }

            for(i=0; i<n; i++)
                r[i][i] = max(1.0,r[i][i]);

            for(k=0; k<n; k++)
                for(i=0; i<n; i++)
                    for(j=0; j<n; j++)
                        r[i][j] = max(r[i][j],r[i][k]*r[k][j]);

            for(i=0; i<n; i++)
                if(r[i][i] > 1.0)
                    break;

            if(i < n)
                System.out.println("case "+cases+" yes");
            else
                System.out.println("case "+cases+" no");
        }
    }

    private static double max(double a, double b){
        return a > b ? a : b;
    }
}

Input & Output

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

4
DM
FF
Schilling
Taler
12
DM 0.5 FF
DM 0.9 Schilling
DM 0.5 Taler
FF 0.5 DM
FF 0.5 Schilling
FF 0.9 Taler
Schilling 0.5 DM
Schilling 0.9 FF
Schilling 0.5 Taler
Taler 1.38 DM
Taler 0.5 FF
Taler 0.5 Schilling

case 1 yes
case 2 no
case 3 yes

Reference

王晓东《计算机算法设计与分析》

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值