hdu 1217

题目概述

给定N种货币,和M条货币间的汇率,问是否可套汇
套汇是指某种货币通过和其他一系列货币兑换,最终兑换回起始币种时汇率大于1的情况

时限

1000ms/2000ms

输入

每组输入第一行正整数N,其后N行,每行一个字符串sa,代表一种货币名称,之后一行正整数M,其后M行,每行一个字符串sa,一个浮点数a,另一个字符串sb,表示1单位sa币可兑换a单位sb币,输入以N=0结束

限制

1<=N<=30;货币名称中不含空格

输出

每行一个字符串,符合以下格式
Case #: @
其中#为数据序数,@当出现套汇时为Yes,否则为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

讨论

图论,floyd算法,用单源最短路也能做,不过那个有点忘却,floyd倒是门清着(毕竟简单),无非就是检查一下有没有环,若有环,查一下绕一圈的权值积是否大于1
输入的数据有字符串,常见的接地气的(放水)表现,弄个字符串到整型的单映射就够了,不过不能用char*比较烦人,还得用string+cin

题解状态

249MS,1816K,985 B,C++

题解代码

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<string>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 32
#define memset0(a) memset(a,0,sizeof(a))

map<string, int>cur;//currency 货币名称到数字的单映射
string sa, sb;//string_a string_b 据说声明字符串很费时 那就循环利用好了
double mat[MAXN][MAXN];//matrix floyd辅助矩阵
int times;//控制Case输出
void fun(int N)
{
    for (int p = 0; p < N; p++) {
        cin >> sa;//input
        cur[sa] = p;//建立一个映射
    }
    int M;//货币兑换条目数
    cin >> M;//input
    for (int p = 0; p < M; p++) {
        double a;//汇率
        cin >> sa >> a >> sb;//input
        mat[cur[sa]][cur[sb]] = a;//初始化floyd矩阵
    }
    for (int p = 0; p < N; p++)
        for (int i = 0; i < N; i++)
            for (int u = 0; u < N; u++)
                mat[i][u] = max(mat[i][u], mat[i][p] * mat[p][u]);//floyd的经典三重循环 这里不是加法 是乘法
    for (int p = 0; p < N; p++)
        if (mat[p][p]>1.0) {//到自身汇率大于1便是套汇
            printf("Case %d: Yes\n", ++times);
            return;//有一组就够
        }
    printf("Case %d: No\n", ++times);
}
int main(void)
{
    //freopen("vs_cin.txt", "r", stdin);
    //freopen("vs_cout.txt", "w", stdout);

    int N;//币种数
    while (cin >> N&&N) {//input
        fun(N);
        cur.clear();
        memset0(mat);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值