现在的位置: 首页 > 综合 > 正文

uva104

2013年02月27日 ⁄ 综合 ⁄ 共 2045字 ⁄ 字号 评论关闭

所謂的「三角套匯(arbitrage)」就是在幾種外幣中做金錢的交易,期待從匯差中獲取少許的利潤。例如:1 元美金可以買 0.7 英鎊,1 元英鎊可以買 9.5 法朗,1 元法朗可以買 0.16 美金。所以如果我們把 1 元美金換成英鎊,再把英鎊換成法朗,最後再把法朗換回美金,那麼最後得到的美金將是:1*0.7*9.5*0.16=1.064 美元。也就是說我們可以從中獲取匯差 0.064 美元,相當於賺了 6.4% 。

請你寫一個程式找出是否有這樣套匯的情況,可以獲取如上所述的利益。

要產生一個成功的套匯,在換外幣的過程中,開始的幣種一定得等於最後的幣種。但是從哪一種開始都可以。

輸入含有多組測試資料。

每組測試資料的第一列,有一個整數 n(2 <= n <= 20),代表共有多少種幣種。

接下來的 n 列代表這n種外幣之間的匯率轉換表。每列有 n-1 個數。這 n-1 個數分別代表該幣種1元可以換取其他幣種多少元(自己換自己當然是 1,所以不會出現)。所以第1列的 n-1 個數依序分別代表第1種外幣1元可以換取,第2種外幣,第3種外幣,第4種外幣...第n種外幣各多少元。而第2列的 n-1 個數依序分別代表第2種外幣1元可以換取,第1種外幣,第3種外幣,第4種外幣...第n種外幣各多少元。依此類推,第n列的
n-1 個數依序分別代表第n種外幣1元可以換取,第1種外幣,第2種外幣,第3種外幣...第n-1種外幣各多少元。

請參考Sample Input

對每組測試資料輸出一列,代表一連串幣種轉換的動作,並且套匯獲利需大於 1%( > 0.01)。如果有不止一種轉換可以獲取超過 1%的利益,請輸出轉換次數最少的。如果轉換次數最少的不止一種,那麼任何一種都可以。請注意:在這裡只要求轉換次數最少,並沒有要求獲利要最大,只要能大於 1% 就可以了。

另外,國稅局還規定最多只能轉換 n 次(n 是幣種的數目)。像 1, 2, 1 這樣的轉換次數為 2。

如果在 n 次的轉換內都無法獲利超過 1%,請輸出 no arbitrage sequence exists。

#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include <algorithm>
#include<queue>
#include<set>
#define LL long long
#define E 1.01
#define M 50
#define N 25
using namespace std;

double ma[N][N][N];
int n;
int path[N][N][N];
void print(int i,int j,int s)
{
  if(s==2)
    {
      printf("%d ",path[2][i][j]);
      return ;
    }
  else
    {
      print(i,path[s][i][j],s-1);
      printf("%d ",path[s][i][j]);
    }
}


int main()
{
#ifndef ONLINE_JUDGE
  freopen("ex.in","r",stdin);
#endif
  while(scanf("%d",&n)!=EOF)
    {
      memset(ma,0,sizeof(ma));
      memset(path,0,sizeof(path));
      for (int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
          if(i==j)
            ma[1][i][j]=1;
          else
            scanf("%lf",&ma[1][i][j]);


      int flag=0;
      for (int i=1; i<=n; i++)
        {
          for(int j=i+1; j<=n; j++)
            {
              if(ma[1][i][j]*ma[1][j][i]-E>0)
                {
                  printf("%d ",i);
                  printf("%d ",j);
                  printf("%d\n",i);//最后不能有空格,pe2次
                  flag=1;
                  break;
                }
            }
          if(flag)            break;
        }
      if(flag)
        continue;
      for(int k=2; k<n; k++)
        {
          for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
              {
                for(int p=1; p<=n; p++)
                  if(ma[k-1][i][p]*ma[1][p][j]>ma[k][i][j])
                    {
                      ma[k][i][j]=ma[k-1][i][p]*ma[1][p][j];
                      path[k][i][j]=p;
                    }
              }
          for (int i=1; i<=n; i++)
            {
              for(int j=i+1; j<=n; j++)
                if(ma[k][i][j]*ma[1][j][i]-E>0)
                  {
                    printf("%d ",i);
                    print(i,j,k);
                    printf("%d ",j);
                    printf("%d",i);
                    flag=1;
                    break;
                  }
              if(flag)            break;
            }
          if(flag)            break;
        }
      if(!flag)
        printf("no arbitrage sequence exists");
      printf("\n");

    }
  return 0;
}

抱歉!评论已关闭.