1. 程式人生 > >POJ 1217 Arbitrage(floyd)

POJ 1217 Arbitrage(floyd)

pri src pac pan from space code namespace 當前

題目大意

貨幣間有一定的匯率可以相互兌換,

給出n種貨幣並告訴m條各貨幣間的匯率,

看這些貨幣中能否有一種可以通過一系列的兌換而增加。 如果是可行的,那麽就輸出Yes,否則輸出No

花Q,博客排版好難啊,就這麽將就吧

理性(瞎JB)分析:

因為匯率就是從一單位的本體開始乘

一直乘到兌換成自己為止

又要讓這一個單位變多 所以直接上啊

即: 能否使一單位該貨幣經一系列兌換後大於一單位

然後因為這道題的n很小,所以直接用floyd也沒關系

30x30x30 = 27000, 小的可憐嘛 代碼的話,註釋已經非常詳細了

技術分享圖片
# include <iostream>
# include 
<string> # include <map> # include <cstdio> # include <cstring> using namespace std; int n, m;//n種貨幣,m條兌換 map<string, int> mp ;//為每種貨幣編號 double d[100][100];//用來儲存 i -> j 的總匯率,即:將每條兌換的匯率相乘所得積 int cnt = 1; //用以計數 Case的序號 char a[35]; char from[35], to[35]; //為避免string必須用cin而有可能導致超時的情況,全部使用char數組
double val;//當前匯率,沒必要全部存下來,反正都存在d[][]裏面了 void floyd(){ for(int k = 0; k < n; k++) for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) if(d[i][j] < d[i][k] * d[k][j]) //如果當前 i -> j的總匯率比新的低,則替換 //匯率高意味著一個單位的貨幣能兌換更多
d[i][j] = d[i][k] * d[k][j]; //floyd標準算法框架,註意本題是匯率,所以相乘而不是相加 for(int i = 0; i < n; i++) //將所有貨幣遍歷一遍 if(d[i][i] > 1.0){ //如果有貨幣在更新了後本身兌換本身的匯率大於 1.0,則能夠套利 printf("Case %d: Yes\n", cnt++); return ; } printf("Case %d: No\n", cnt++); return ; } int main(){ while(~scanf("%d", &n), n){ memset(d, 0, sizeof(d)); // 處理每組樣例時將d[][]初始化 for(int i = 0; i < n; i++){ scanf("%s", a); mp[a] = i; //為貨幣編號 } scanf("%d", &m); for(int i = 0; i < m; i++){ scanf("%s%lf%s", from, &val, to); //字符串用 s, double類型用 lf //char數組的名字是一個指針,所以不用加 & //即對char a[] : &a[0] = a d[mp[from]][mp[to]] = val; //保存各貨幣間的匯率 } floyd();//處理 } return 0; }
View Code

POJ 1217 Arbitrage(floyd)