Show Me the Money

来源:互联网 发布:乒乓球直播软件 编辑:程序博客网 时间:2024/05/17 03:42
Show Me the Money


Frank Marks works at the Business Office of a large company. His company has customers all over the world and must deal with many different currencies. Employees often come  to the Business Office with requisitions for certain amounts of money, such as 100 American dollars or 452 Euros. If Frank has
the cash on hand, he gives the employee exactly what they need; if he does not have enough of the particular currency requested, he substitutes it with another one. This is sometimes difficult because he may have many different currencies to choose from and would like to pick the one which allows him to get as close to the original requisition as possible without going under (he must provide at least the value requested). For example, suppose Frank has six difference currencies – A, B, C, D, E and F – and he is aware of the following exchange rates:


        23 A = 17 B
        16 C = 29 E
        5 B = 14 E
        1 D = 7 F


If a requisition for 100 A comes in but Frank has less than 100 A available, he can substitute with either 74 B (equivalent to about 100.12 A), 115 C (equivalent to about 100.72 A) or 207 E (equivalent to about 100.02 A). Thus, the best approximation available to him is 207 E. Note that Frank does not have enough information to find a relationship between currencies A and D or currencies A and F. Also, Frank only has at most 100,000 units of any one currency in stock, so he could not satisfy a request for 64,000 A using E currency and would need to use 73078 C instead. 


Determining the ideal substitute currency to use when he has completely run out of the requested currency is time consuming, so Frank would like a program to do the calculations for him.


Input


Each test case begins with a positive integer n indicating the number of exchange rates. The next n lines will be of the form   val1 name1 = val2 name2 
where name1 and name2 are the names of two distinct currencies, and val1 and val2 are positive integers ≤ 30 specifying the ratio between the two currencies. There will be no more than 8 distinct currency names, and any two currencies will be paired together at most once. Currency names will consist of up to ten alphabetic characters. There will be no inconsistencies in the input (such as 1A = 2B, 1B = 2C and 1C = 2A). Following these n lines will be a single line of the form 
            val name 
which specifies the amount (a positive integer not exceeding 100,000) and the name of the currencyrequested. A line containing 0 will follow the last test case.


Output


For each test case, print the case number and the closest approximation without going under the requested value assuming that Frank does not have any of the requested currency available but is fully in stock of all other currencies. There will be a unique answer for each problem instance.


Sample Input


4
23 A = 17 B
16 C = 29 E
5 B = 14 E
1 D = 7 F
100 A
1
1 shekel = 2 quatloo
40 quatloo
0


Sample Output


Case 1: 207 E

Case 2: 20 shekel


题目大意:给出n种货币兑换的比例,求用多少 哪一种货币 兑换出不少于给定数量的给定货币的 差值最小,货币种类不超过8中,兑换比例不会出现自相矛盾的情况,且每两种货币之间的兑换比例最多给出一次。

这题大概是我过得最迷的一题了,maxn定为50的时候可以AC,maxn=100不可以过,后来改了改,maxn=100可以AC了,结果maxn=80的时候WA的不知所措QAQ,好像是哪里的未定义行为,找了一个晚上都没有找到在哪里,只是玄学的改了一些地方后,使得可以在maxn=50和80可以AC,但是maxn=50时又会WA。简直无力了。

暂时正确的代码(  ┑( ̄Д  ̄)┍,只有这个了)

#include <cmath>#include <queue>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <map>#include <set>#define maxn 50using namespace std;long long n;string A,B;set< string > S;map< string ,long long > M;map< long long ,string > _M;long long cnt;long long get_num(string x){if (S.count( x )==0)    {        ++cnt;        S.insert( x );        M.insert( make_pair( x, cnt ) );        _M.insert( make_pair( cnt , x ) );    }return M[x];}long double g[maxn][maxn][2];bool vis[maxn][maxn];const long double INF=10000000;int main(){    int T;    while (scanf("%d",&n)!=EOF )        {            if (n==0)                break;            cnt=0;            M.clear();            _M.clear();            S.clear();            memset(g,0,sizeof(g));            memset(vis,0,sizeof(vis));            for (long long i=1;i<=n;i++)                {                    long double a,b;                    cin>>a; cin>>A;                    long long x=get_num(A);                    cin>>A;                    cin>>b; cin>>B;                    long long y=get_num(B);                    g[x][y][0]=a;                    g[x][y][1]=b;                    g[y][x][0]=b;                    g[y][x][1]=a;                    vis[x][y]=1;                    vis[y][x]=1;                }            long double m;            cin>>m;            cin>>A;            for (long long k=1;k<=cnt;k++)                for (long long i=1;i<=cnt;i++)                if (vis[i][k])                    for (long long j=1;j<=cnt;j++)                    if (vis[k][j])                        if ( (i!=j)&&(j!=k)&&(i!=k) )                            if (!vis[i][j])                        {                            vis[i][j]=1;                            g[i][j][0]= g[i][k][0]*g[k][j][0] ;                            g[i][j][1]= g[i][k][1]*g[k][j][1] ;                        }            long long x=M[A];            long double ans=INF;            long long ansy=0;            long long ansi=0;            for (long long i=1;i<=cnt;i++)                if (g[x][i][0]!=0)                    if (i!=x)                    {                        long long y=ceil( ( m*g[x][i][1]/ g[x][i][0] ) - ( 1e-8) );                        if ( (y>0)&&(  y<= 100000 ) )                        {                            if ( (y*g[i][x][1]*(1.0/g[i][x][0])-m) >= -( 1e-8) )                            if ( ( y*g[i][x][1]*(1.0/g[i][x][0])-m < ans ) || (ansi==0) )                                {                                    ans=y*g[i][x][1]*(1.0/g[i][x][0])-m;                                    ansi=i;                                    ansy=y;                                }                        }                    }            T++;            printf("Case %d: ",T);            cout<<ansy<<" ";            cout<<_M[ ansi ]<<endl;        }    return 0;}