zoukankan      html  css  js  c++  java
  • Currency Exchange POJ

    Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the same pair of currencies. Each point has its own exchange rates, exchange rate of A to B is the quantity of B you get for 1A. Also each exchange point has some commission, the sum you have to pay for your exchange operation. Commission is always collected in source currency. 
    For example, if you want to exchange 100 US Dollars into Russian Rubles at the exchange point, where the exchange rate is 29.75, and the commission is 0.39 you will get (100 - 0.39) * 29.75 = 2963.3975RUR. 
    You surely know that there are N different currencies you can deal with in our city. Let us assign unique integer number from 1 to N to each currency. Then each exchange point can be described with 6 numbers: integer A and B - numbers of currencies it exchanges, and real RAB, C AB, R BA and C BA - exchange rates and commissions when exchanging A to B and B to A respectively. 
    Nick has some money in currency S and wonders if he can somehow, after some exchange operations, increase his capital. Of course, he wants to have his money in currency S in the end. Help him to answer this difficult question. Nick must always have non-negative sum of money while making his operations. 

    Input

    The first line of the input contains four numbers: N - the number of currencies, M - the number of exchange points, S - the number of currency Nick has and V - the quantity of currency units he has. The following M lines contain 6 numbers each - the description of the corresponding exchange point - in specified above order. Numbers are separated by one or more spaces. 1<=S<=N<=100, 1<=M<=100, V is real number, 0<=V<=10 3
    For each point exchange rates and commissions are real, given with at most two digits after the decimal point, 10 -2<=rate<=10 2, 0<=commission<=10 2
    Let us call some sequence of the exchange operations simple if no exchange point is used more than once in this sequence. You may assume that ratio of the numeric values of the sums at the end and at the beginning of any simple sequence of the exchange operations will be less than 10 4

    Output

    If Nick can increase his wealth, output YES, in other case output NO to the output file.

    Sample Input

    3 2 1 20.0
    1 2 1.00 1.00 1.00 1.00
    2 3 1.10 1.00 1.10 1.00
    

    Sample Output

    YES

    题意:有m家银行,每家银行能兑换两种货币,兑换货币需要手续费,且有货币兑换率,例如,如果你想在兑换点把100美元兑换成俄罗斯卢布,兑换率是29.75,佣金是0.39,你会得到(100-0.39)*29.75=2963.3975卢布。这个世界
    共有n中货币。你的目的是将你的货币兑换成第n种货币后,你手中的钱比你原来的多。输入第一行,四个数:n种货币,m家银行,你现在的货币是第s种货币,你现在有数量为v的钱数。往后为m行,每行有六个数字:银行能兑换的货币种类
    a,b,从a到b的汇率c和手续费d,从b到a的汇率e和手续费f.

    思路:兑换你手中的钱在各个银行中,如果兑换后钱数并没有减少,就是赚了。可以转换为:每种货币为一个点,点之间的连线为边,如果你从起点到终点的过程中没有负权,则整个过程过后,你的钱并不会减少。
    利用Bellman-Ford 算法的思想,但你要求的是没有负权,只需要对Bellman-Ford 算法做一些改变即可。

    代码:
      1 #include <cstdio>
      2 #include <fstream>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <deque>
      6 #include <vector>
      7 #include <queue>
      8 #include <string>
      9 #include <cstring>
     10 #include <map>
     11 #include <stack>
     12 #include <set>
     13 #include <sstream>
     14 #include <iostream>
     15 #define mod 998244353
     16 #define eps 1e-6
     17 #define ll long long
     18 #define INF 0x3f3f3f3f
     19 using namespace std;
     20 
     21 
     22 //dis用来存放到起点之间的距离
     23 double dis3[110];
     24 //存的起点和终点
     25 int qiz[210][2];
     26 //存款的手续费
     27 double sxf[210][2];
     28 //边的数量
     29 int ans;
     30 
     31 //修改后的bellman算法,用于求正环
     32 //start表示初始点,n表示点的个数,v表示初始钱数
     33 bool bellman(int start,int n,double v)
     34 {
     35     //由于dis3数组为double类型,所以用for来初始化
     36     for(int i=0;i<=n;i++)
     37     {
     38         dis3[i]=0;
     39     }
     40     //初始化起点
     41     dis3[start]=v;
     42     //遍历n-1次
     43     for(int i=1;i<n;i++)
     44     {
     45         //flag优化,false表示有负权
     46         bool flag=false;
     47         //遍历所有边
     48         for(int j=1;j<=ans;j++)
     49         {
     50             int a=qiz[j][0];
     51             int b=qiz[j][1];
     52             //如果转换货币后钱数增加,则代表这两点之间为正权
     53             if(dis3[b]<((dis3[a]-sxf[j][1])*sxf[j][0]))
     54             {
     55                 dis3[b]=((dis3[a]-sxf[j][1])*sxf[j][0]);
     56                 flag=true;
     57             }
     58         }
     59         //如果遍历所有边后数据增加,表示有负权
     60         if(!flag)
     61         {
     62             return false;
     63         }
     64     }
     65     //遍历n-1遍后,应当得出所有数据
     66     for(int i=1;i<=ans;i++)
     67     {
     68         //但钱数还能增加,表示有正权
     69         if(dis3[qiz[i][1]]<((dis3[qiz[i][0]]-sxf[i][1])*sxf[i][0]))
     70         {
     71             return true;
     72         }
     73     }
     74     return false;
     75 }
     76 int main()
     77 {
     78     //n表示货币种类,m表示银行的数量,s表示你有的货币种类
     79     int n,m,s;
     80     //v表示你有的钱数
     81     double v;
     82     //初始边为1
     83     ans=1;
     84     scanf("%d %d %d %lf",&n,&m,&s,&v);
     85     //a,b记录货币种类
     86     int a,b;
     87     //c,e为汇率,d,f为手续费
     88     double c,d,e,f;
     89     for(int i=1;i<=m;i++)
     90     {
     91         scanf("%d %d %lf %lf %lf %lf",&a,&b,&c,&d,&e,&f);
     92         //记录从a到b的数据
     93         qiz[ans][0]=a;
     94         qiz[ans][1]=b;
     95         sxf[ans][0]=c;
     96         sxf[ans][1]=d;
     97         ans++;
     98         //记录从b到a的数据
     99         qiz[ans][0]=b;
    100         qiz[ans][1]=a;
    101         sxf[ans][0]=e;
    102         sxf[ans][1]=f;
    103         ans++;
    104     }
    105     //判断是否有负环
    106     if(bellman(s,n,v))
    107     {
    108         printf("YES
    ");
    109     }
    110     else
    111     {
    112         printf("NO
    ");
    113     }
    114 }
  • 相关阅读:
    正则,ant antd from验证input框只能输入数字
    React 实现简易轮播图
    Moment.js ,JavaScript 日期处理类库
    JavaScript中准确的判断数据类型--四种方法
    介绍:一款可以描绘圆圈进度条的jQuery插件(可用作统计图)
    给网页增加水印的方法,react
    IntelliJ IDEA创建web项目及异常问题解决
    CSS 代码是什么?(转)
    JSP入门:介绍什么是JSP和Servlet(转)
    INTELLIJ IDEA集成CHECKSTYLE(转)
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11479436.html
Copyright © 2011-2022 走看看