題目描述
恰逢 HH 國國慶,國王邀請 nn 位大臣來玩一個有獎遊戲。首先,他讓每個大臣在左、右手上面分別寫下一個整數,國王自己也在左、右手上各寫一個整數。然後,讓這 nn 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是:排在該大臣前面的所有人的左手上的數的乘積除以他自己右手上的數,然後向下取整得到的結果。
國王不希望某一個大臣獲得特別多的獎賞,所以他想請你幫他重新安排一下隊伍的順序,使得獲得獎賞最多的大臣,所獲獎賞儘可能的少。注意,國王的位置始終在隊伍的最前面。
輸入輸出格式
輸入格式:
第一行包含一個整數 nn ,表示大臣的人數。
第二行包含兩個整數 aa 和 bb ,之間用一個空格隔開,分別表示國王左手和右手上的整數。
接下來 nn 行,每行包含兩個整數 aa 和 bb ,之間用一個空格隔開,分別表示每個大臣左手和右手上的整數。
輸出格式:
一個整數,表示重新排列後的隊伍中獲獎賞最多的大臣所獲得的金幣數。
輸入輸出樣例
輸入樣例#1: 複製
3 1 1 2 3 7 4 4 6
輸出樣例#1: 複製
2
說明
【輸入輸出樣例說明】
按 11 、 22 、 33 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數爲 22 ;
按 11 、 33 、 22 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數爲 22 ;
按 22 、 11 、 33 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數爲 22 ;
按 22 、 33 、 11 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數爲 99 ;
按 33 、 11 、 22 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數爲 22 ;
按 33 、 22 、 11 這樣排列隊伍,獲得獎賞最多的大臣所獲得金幣數爲 99 。
因此,獎賞最多的大臣最少獲得 22 個金幣,答案輸出 22 。
【數據範圍】
對於 20%的數據,有 1≤ n≤ 10,0 < a,b < 81≤n≤10,0<a,b<8 ;
對於 40%的數據,有 1≤ n≤20,0 < a,b < 81≤n≤20,0<a,b<8 ;
對於 60%的數據,有 1≤ n≤1001≤n≤100 ;
對於 60%的數據,保證答案不超過 10^9109 ;
對於 100%的數據,有 1 ≤ n ≤1,000,0 < a,b < 100001≤n≤1,000,0<a,b<10000 。
這題貪心部分不難,主要是有一個大數的乘除運算,我一開始就沒有注意到這個,然後無恥的看了大佬的題解。。。
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int n,ans,g[1000001],l = 1;
struct pep{
double left,right;
};
bool cmp(pep a, pep b){
return a.left*a.right < b.left*b.right;
}
void prin(){
for(int j = l-1; j >= 0; j --)
cout << g[j];
}
void adsum(int k){
{
for(int i=0;i<l;i++) g[i]*=k;
for(int i=0;i<l;i++)
{
g[i+1]+=(g[i]/10);
g[i]%=10;
}
l++;
while(g[l-1]>9)
{
g[l]+=(g[l-1]/10);
g[l-1]%=10;
l++;
}
if(g[l-1]==0) l--;
}
}
void devsum(int k)
{ for(int i=l-1;i>=0;i--)
{
g[i-1]+=((g[i]%k)*10);
g[i]/=k;
}
while(g[l-1]==0) l--;
if(l==0) printf("1\n");
}
int main() {
double max = 0,sum;
cin >> n;
pep p[n+1];
for(int i = 0; i < n+1; i ++){
cin >> p[i].left >> p[i].right;
}
sort(p+1,p+n+1,cmp);
//sum = p[0].left;
g[0] = p[0].left;
for(int i = 1; i < n; i ++){
adsum(p[i].left);
}
devsum(p[n].right);
prin();
return 0;
}