通过观察,可以发现当每个人根据手中a*b的值,从小到大排列时,可以得到符合要求的答案,即获得奖赏最多的大臣所获奖赏尽可能少。
本题的一大难点是高精度。此题需要写高精度的乘法函数,和除法函数。
但不会写,看了题解后照着题解打出来的代码
#include<bits/stdc++.h>
using namespace std;
int ans[20010],sum[20010],store_ans[20010];
struct node
{
int a,b;
}a[5005];
bool cmp(node s1,node s2){
return s1.a*s1.b<s2.a*s2.b;
}
int read() {
int ans1=0,flag=1;
char ch=getchar();
while( (ch>'9' || ch<'0') && ch!='-' ) ch=getchar();
if(ch=='-') flag=-1,ch=getchar();
while(ch>='0' && ch<='9') ans1=ans1*10+ch-'0',ch=getchar();
return ans1*flag;
}
void multiplication(int x){
memset(store_ans,0,sizeof(store_ans));
for(int i=1;i<=ans[0];i++){
ans[i]=ans[i]*x;
store_ans[i+1]+=ans[i]/10;
ans[i]%=10;
}
for(int i=1;i<ans[0]+4;i++){
ans[i]+=store_ans[i];
if(ans[i]>10){
ans[i+1]+=ans[i]/10;
ans[i]%=10;
}
if(ans[i]!=0){
ans[0]=max(ans[0],i);
}
}
}
int division(int x){
memset(store_ans,0,sizeof(store_ans));
int q=0;
for(int i=ans[0];i>0;i--){
q*=10;
q+=ans[i];
store_ans[i]=q/x;
if(store_ans[0]==0&&store_ans[i]!=0){
store_ans[0]=i;
}
q%=x;
}
return 0;
}
bool compare() {
if(sum[0]==store_ans[0]) {
for(int i=store_ans[0];i>=1;i--) {
if(store_ans[i]>sum[i]) return 1;
if(store_ans[i]<sum[i]) return 0;
}
}
if(store_ans[0]>sum[0]) return 1;
if(store_ans[0]<sum[0]) return 0;
}
void cp () {
memset(sum,0,sizeof(sum));
for(int i=store_ans[0];i>=0;i--) {
sum[i]=store_ans[i];
}
return ;
}
int main()
{
int m=read();
for(int i=0;i<=m;i++)
a[i].a=read(),a[i].b=read();
sort(a+1,a+1+m,cmp);
ans[0]=1;ans[1]=1;
for(int i=1;i<=m;i++) {
multiplication(a[i-1].a);
division(a[i].b);
if(compare()) {
cp();
}
}
for(int i=0;i<=m;i++)
printf("%d %d\n",a[i].a,a[i].b);
for(int i=sum[0];i>=1;i--)
printf("%d",sum[i]);
return 0;
}