luogu 1080 国王游戏

题目大意:

有一些数对,每个数对的得分为它之前所有数对的左侧数之乘积除以它的右侧数

求重新排列后数列中所有数对中最大得分尽可能小(第一个数对不参与排序,仍然为第一个)

思路:

非常简单,可以根据它对后面的影响排序

即若a i.l/a j.r < a j.l/a i.r则a i在a j前

则a i.l * a i.r < a j.l * a j.r则a i在a j前

那么我只需要一个重载运算符

但是呢,数据较大需要高精度

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #define inf 2147483647
13 #define ll long long
14 #define MOD 1000000000
15 #define MAXN 1010
16 using namespace std;
17 inline int read()
18 {
19     int x=0,f=1;
20     char ch=getchar();
21     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
22     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
23     return x*f;
24 }
25 int n;
26 struct data 
27 {
28     int l,r;
29     bool operator < (const data &a) const
30     {
31         return (l*r<a.l*a.r)||(l*r==a.l*a.r&&r<a.r);
32     }
33 }g[MAXN];
34 struct bign
35 {
36     ll num[MAXN*5];
37     int len;
38     bign() {memset(num,0,sizeof(num));len=0;}
39     void mul(int a)
40     {
41         ll k=0;
42         for(int i=0;i<=len;i++)
43         {
44             num[i]=num[i]*a+k;
45             k=num[i]/MOD;
46             num[i]%=MOD;
47         }
48         if(k) {len++;num[len]=k;}
49     }
50     bign div(int a)
51     {
52         ll k=0;
53         bign res;res.len=len;
54         for(int i=len;i>=0;i--)
55         {
56             res.num[i]=(num[i]+k)/a;
57             k=((num[i]+k)%a)*MOD;
58         }
59         if(!res.num[len]&&res.len) res.len--;
60         return res;
61     }
62     void print()
63     {
64         printf("%d",num[len]);
65         for(int i=len-1;i>=0;i--)
66         {
67             printf("%09d",num[i]);
68         }
69     }
70 }tmp,ans;
71 void amax(bign b)
72 {
73     bool flag=0;
74     if(ans.len>b.len) return ;
75     if(ans.len<b.len)
76     {
77         ans.len=b.len;
78         for(int i=ans.len;i>=0;i--) ans.num[i]=b.num[i];
79         return ;
80     }
81     for(int i=ans.len;i>=0;i--)
82         if(ans.num[i]<b.num[i]) {flag=1;break;}
83     if(flag)
84         for(int i=ans.len;i>=0;i--) ans.num[i]=b.num[i];
85 }
86 int main()
87 {
88     n=read();
89     int a=read(),b=read();
90     for(int i=1;i<=n;i++) g[i].l=read(),g[i].r=read();
91     sort(g+1,g+n+1);
92     tmp.num[0]=a;
93     for(int i=1;i<=n;i++)
94     {
95         amax(tmp.div(g[i].r));
96         tmp.mul(g[i].l);
97     }
98     ans.print();
99 }
View Code

orz 写了个压位,又是小技巧调一年

第一次是因为没搞清楚*=的优先级

然后是因为除法考虑余数时算错了数组

原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7678968.html