首页 > 代码库 > codevs1198 国王游戏

codevs1198 国王游戏

题目描述 Description

恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

输入描述 Input Description

第一行包含一个整数 n,表示大臣的人数。

第二行包含两个整数a和b,之间用一个空格隔开,分别表示国王左手和右手上的整数。

接下来n行,每行包含两个整数a和b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

输出描述 Output Description

输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的

金币数。

样例输入 Sample Input

3

1 1

2 3

7 4

4 6

样例输出 Sample Output

2

数据范围及提示 Data Size & Hint

【输入输出样例说明】

按 1、2、3号大臣这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按 1、3、2这样排列队伍,获得奖赏最多的大臣所获得金币数为2;

按 2、1、3这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按 2、3、1这样排列队伍,获得奖赏最多的大臣所获得金币数为 9;

按 3、1、2这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按 3、2、1这样排列队伍,获得奖赏最多的大臣所获得金币数为 9。

因此,奖赏最多的大臣最少获得 2 个金币,答案输出 2。

 

【数据范围】

对于20%的数据,有1≤ n≤ 10,0 < a、b < 8;

对于40%的数据,有1≤ n≤20,0 < a、b < 8;

对于60%的数据,有1≤ n≤100;

对于60%的数据,保证答案不超过 10^9;

对于100%的数据,有 1 ≤ n ≤1,000,0 < a、b < 10000。

 

思路:
(摘自夏令营课件)

首先,相邻两个人交换位置,对其他人获得的奖赏没有影响。 设A、B相邻,A的左右手分别是a、b, B的左右手分别是c、d。A、B之前大臣左手的乘积是t。 A在B前,A获得t/b,B获得at/d。 B在A前,A获得ct/b,B获得t/d。 因为t/b<ct/b,t/d<at/d 所以总的最大值是at/d或ct/b

a/d>c/b,即ab>cd时, A在B前会更大,所以让B在A前 a/d<c/b,即ab<cd时, B在A前会更大,所以让A在B前 所以按左右手上数的乘积从小到大排序。

代码:

(注意高精度)

#include <cstdio> #include<algorithm> #include <cmath> #include <iostream> #include <cstring>  using namespace std;  const int P=10000,L=5000,W=4; char s[L*W]; struct Big   {     int len;int data[L];bool fu;     void clear()        {         memset(data,0,sizeof(data));         len=0;fu=false;       }     int& operator [] (int k)       {         return data[k];       }     void operator = (int k)       {         clear();         if (k<0) fu=true,k=-k;else fu=false;         len=0;         while (k) data[++len]=k%P,k/=P;          if (len==0) len=1;       }     bool operator < (Big b)       {         bool t=false;         if (fu && !b.fu) return true;         if (!fu && b.fu) return false;         if (fu && b.fu) t=true;         if (len<b.len) return true^t;         if (len>b.len) return false^t;         for (int i=len;i;--i)           {             if (data[i]<b[i]) return true^t;             if (data[i]>b[i]) return false^t;           }         return false;       }     bool operator <= (Big b)       {         bool t=false;         if (fu && !b.fu) return true;         if (!fu && b.fu) return false;         if (fu && b.fu) t=true;         if (len<b.len) return true^t;         if (len>b.len) return false^t;         for (int i=len;i;--i)           {             if (data[i]<b[i]) return true^t;             if (data[i]>b[i]) return false^t;           }         return true;       }     bool operator > (Big b)       {         bool t=false;         if (fu && !b.fu) return false;         if (!fu && b.fu) return true;         if (fu && b.fu) t=true;         if (len<b.len) return false^t;         if (len>b.len) return true^t;         for (int i=len;i;--i)           {             if (data[i]<b[i]) return false^t;             if (data[i]>b[i]) return true^t;           }         return false;       }     bool operator >= (Big b)       {         bool t=false;         if (fu && !b.fu) return false;         if (!fu && b.fu) return true;         if (fu && b.fu) t=true;         if (len<b.len) return false^t;         if (len>b.len) return true^t;         for (int i=len;i;--i)           {             if (data[i]<b[i]) return false^t;             if (data[i]>b[i]) return true^t;           }         return true;       }     bool operator == (Big b)       {         if (fu!=b.fu) return false;         if (len<b.len) return false;         if (len>b.len) return false;         for (int i=len;i;--i)           if (data[i]!=b[i]) return false;         return true;       }     bool operator == (int k)       {         if (k<0)           {             if (!fu) return false;             k=-k;           } else if (fu) return false;         if (k>=P)           {             Big b;b=k;             return *this==b;           }             else return len==1 && data[1]==k;       }     bool operator != (Big b)       {         if (fu!=b.fu) return true;         if (len<b.len) return true;         if (len>b.len) return true;         for (int i=len;i;--i)           if (data[i]!=b[i]) return true;         return false;       }     bool operator != (int k)       {         if (k<0)           {             if (!fu) return true;             k=-k;           } else if (fu) return true;         if (k>=P)           {             Big b;b=k;             return *this!=b;           }             else return !(len==1 && data[1]==k);       }     Big operator + (Big b)       {         Big a=*this,c;c.clear();         if (a.fu && b.fu)            {             a.fu=false;b.fu=false;c=a+b;             if (c.len!=1 || c[1]!=0) c.fu=true;             return c;           }         if (a.fu && !b.fu)            {a.fu=false;return b-a;}         if (!a.fu && b.fu)           {b.fu=false;return a-b;}          a.len=max(a.len,b.len);         for (int i=1;i<=a.len;++i)           {             a[i+1]+=(a[i]+b[i])/P;             a[i]=(a[i]+b[i])%P;           }         if (a[a.len+1]) ++a.len;         while (a[a.len]==0 && a.len>1) --a.len;         return a;       }     Big operator + (int k)       {         Big a=*this,b;b=k;         return a+b;       }     Big operator - (Big b)       {         Big a=*this,c;c.clear();         if (a.fu && !b.fu)           {             a.fu=false;b.fu=false;c=a+b;             if (c.len!=1 || c[1]!=0) c.fu=true;             return c;           }         if (a.fu && b.fu)            {             a.fu=false;b.fu=false;return b-a;           }         if (!a.fu && b.fu)           {             b.fu=false; return a+b;           }         if (a<b) swap(a,b),a.fu=true;else a.fu=false;         for (int i=1;i<=a.len;++i)           {             if (a[i]<b[i]) a[i]+=P,--a[i+1];             a[i]-=b[i];           }         while (a[a.len]==0 && a.len>1) --a.len;         if (a.len==1 && a[1]==0) a.fu=false;         return a;       }     Big operator - (int k)       {         Big a=*this,b;b=k;         return a-b;       }     Big operator * (Big b)       {         Big c;c.clear();         c.len=len+b.len-1;         for (int i=1;i<=len;++i)           for (int j=1;j<=b.len;++j)             {               c[i+j-1]+=data[i]*b[j];               c[i+j]+=c[i+j-1]/P;               c[i+j-1]%=P;             }         if (c[c.len+1]) ++c.len;         while (c[c.len]==0 && c.len>1) --c.len;         c.fu=fu^b.fu;         if (c.len==1 && c[1]==0) c.fu=false;         return c;       }     Big operator * (int k)       {         Big a=*this;         if (k<0) a.fu=!a.fu,k=-k;         if (k>=P)            {             Big b;b=k;             return a*b;           }         for (int i=1;i<=a.len;++i) a[i]*=k;         for (int i=1;i<=a.len;++i)           a[i+1]+=a[i]/P,a[i]%=P;         while (a[a.len+1])            {             ++a.len;             a[a.len+1]=a[a.len]/P;             a[a.len]%=P;           }         while (a[a.len]==0 && a.len>1) --a.len;         if (a.len==1 && a[1]==0) a.fu=false;         return a;       }     Big operator / (int k)       {         Big a=*this;int g=0;         if (k<0) a.fu=!a.fu,k=-k;         for (int i=a.len;i;--i)           {             a[i]+=g*P;             g=a[i]%k;             a[i]/=k;           }         while (a[a.len]==0 && a.len>1) --a.len;         if (a.len==1 && a[1]==0) a.fu=false;         return a;       }     Big operator % (int k)       {         Big b;b=k;         return *this%b;       }     Big operator / (Big b)       {         Big c,d;c=0;d=0;c.fu=fu^b.fu;b.fu=false;         for (int i=len;i;--i)           {             d=d*P+data[i];             int ans=0,l=0,r=P-1;             while (l<=r)               {                 int mid=(l+r)>>1;                 if (b*mid<=d) ans=mid,l=mid+1;                 else r=mid-1;               }             c[i]=ans;             d=d-b*c[i];           }         c.len=len;         while (c[c.len]==0 && c.len>1) --c.len;         return c;       }     Big operator % (Big b)       {         Big c,d;c=0;d=0;c.fu=fu^b.fu;b.fu=false;         for (int i=len;i;--i)           {             d=d*P+data[i];             int ans=0,l=0,r=P-1;             while (l<=r)               {                 int mid=(l+r)>>1;                 if (b*mid<=d) ans=mid,l=mid+1;                 else r=mid-1;               }             c[i]=ans;             d=d-b*c[i];           }         c.len=len;         while (c[c.len]==0 && c.len>1) --c.len;         d=*this-b*c;         return d;       }     Big operator ^ (int t)       {         Big a=*this,ans;ans=1;         while (t)           {             if (t&1) ans=ans*a;t>>=1;a=a*a;           }         return ans;       }         void read()       {         scanf("%s",s);         clear();         len=1;         int pow=1,t=1,l=strlen(s),stop=0;         if (s[0]==-) fu=true,stop=1;         for (int i=l-1;i>=stop;--i)           {             if (t>W) t=pow=1,++len;             data[len]+=pow*(s[i]-0);             ++t,pow*=10;           }       }     void write()       {         if (fu) printf("%c",-);         printf("%d",data[len]);         for (int i=len-1;i;--i)           {             if (data[i]<10) putchar(0);             if (data[i]<100) putchar(0);             if (data[i]<1000) putchar(0);             printf("%d",data[i]);           }       }     void writeln()       {         write();printf("\n");       }   } ;  struct Man{      int l;      int r;      Big sum;  };  bool cmp(Man a,Man b){      return (a.l * a.r) < (b.l * b.r);  }  Big ans,lft;   Man man[1005];int main(){    int n,fl,fr;    cin>>n;    cin>>fl>>fr;    for(int i = 0;i < n;i++){        cin>>man[i].l>>man[i].r;        man[i].sum = man[i].l * man[i].r;    }    sort(man,man + n,cmp);    ans = 0;    lft = fl;    for(int i = 0;i < n;i++){        if(lft * man[i].r > ans) ans = lft / man[i].r;        lft = lft * man[i].l;    }    if(ans == 0) cout<<1<<endl;    else ans.writeln();    return 0;}

 

codevs1198 国王游戏