恰逢 H 國國慶,國王邀請 n 位大臣來玩一個有獎遊戲。
首先,他讓每個大臣在左、右手上面分別寫下一個整數,國王自己也在左、右手上各寫一個整數。
然後,讓這 n 位大臣排成一排,國王站在隊伍的最前面。
排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是:
排在該大臣前面的所有人的左手上的數的乘積除以他自己右手上的數,然後向下取整得到的結果。
國王不希望某一個大臣獲得特別多的獎賞,所以他想請你幫他重新安排一下隊伍的順序,使得獲得獎賞最多的大臣,所獲獎賞儘可能的少。
注意,國王的位置始終在隊伍的最前面。
輸入格式
第一行包含一個整數 n,表示大臣的人數。
第二行包含兩個整數 a 和 b,之間用一個空格隔開,分別表示國王左手和右手上的整數。
接下來 n 行,每行包含兩個整數 a 和 b,之間用一個空格隔開,分別表示每個大臣左手和右手上的整數。
輸出格式
輸出只有一行,包含一個整數,表示重新排列後的隊伍中獲獎賞最多的大臣所獲得的金幣數。
數據範圍
1≤n≤1000
0<a,b<10000
輸入樣例:
3
1 1
2 3
7 4
4 6
輸出樣例:
2
這個題太噁心了,調了接近一個小時才調出來,,fo了
思路:貪心,將所有數按左右手相加總和從小到大排序,一定滿足題目所說的最大值最小,這個證明比較麻煩,想看的可以戳這裏 貪心證明 接下來模擬就可以了。
代碼:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 1005;
struct node
{
int x,y;
bool operator < (node m) const
{
return x+y<m.x+m.y;
}
}a[N];
string multi(string a,int b)
{
string ans("");
int t=0;
if(a.size()==1 && a[0]=='0') a[0]='1';
reverse(a.begin(),a.end());
for(int i=0;(i<a.size())||t;i++)
{
if(i<a.size())
t+=(a[i]-'0')*b;
ans+=t%10+'0';
t/=10;
}
reverse(ans.begin(),ans.end());
return ans;
}
string divide(string a,int b)
{
string ans("");
int t=0;
for(int i=0;i<a.size();i++)
{
t=t*10+a[i]-'0';
ans+=t/b+'0';
t%=b;
}
int i=0;while(i<ans.size()-1&&ans[i]=='0') i++;
string x(ans,i,ans.size()-i+1);
return x;
}
bool comp(string a,string b)
{
if(a.size()!=b.size())
return a.size()<b.size();
for(int i=0;i<a.size();i++)
if(a[i]!=b[i])
return a[i]-'0'<b[i]-'0';
return true;
}
int main()
{
int n;
cin>>n;
for(int i=0;i<=n;i++)
cin>>a[i].x>>a[i].y;
sort(a+1,a+n+1);
string ans,sum,tem;
tem="0";ans="0";sum="0";
for(int i=0;i<=n;i++)
{
tem=divide(sum,a[i].y);
if(comp(ans,tem)) ans=tem;
sum=multi(sum,a[i].x);
}
cout<<ans<<endl;
return 0;
}