今天写了洛谷的P1080
没错
一道贪心题
其实邻项交换在lyd《算法竞赛进阶指南》里读到过了
推导就不说了 跟丘砖逆序对那章有点神似(?
但是写该死的高精还是花了好久
看代码吧
高精的题目看来得多练 不然上考场老是出事
#include<bits/stdc++.h> #define ll long long using namespace std; struct node{int l,r; }; node q[1005]; int n,sx,sy,len,f,maxxlen; int a[10005],tem[10005],fa[10005],maxx[10005];//这里s和a解出来都是反的sx 用于乘法的简便 而fa才是真正的sx 用于除法的简便 char s[10005]; bool cmp(node x,node y){if(x.l*x.r==y.l*y.r) return x.r<y.r;else return x.l*x.r<y.l*y.r; } void mult(int a[],int b){//高精乘低精的模板题memset(tem,0,sizeof(tem));for(int i=1;i<=len;i++) tem[i]=a[i]*b;for(int i=1;i<=len;i++){if(tem[i]/10){tem[i+1]+=tem[i]/10;tem[i]%=10;}while(tem[len+1]) len++;while(tem[len]/10){tem[len+1]+=tem[len]/10;tem[len]%=10;len++;}//这堆要放在括号里面 这样好像比较严谨(?) 反正模版也是拿来背的}for(int i=1;i<=len;i++) a[i]=tem[i]; } void divv(int a[],int b){//高精除低精以及两个高精数的比较memset(tem,0,sizeof(tem));int x=0;for(int i=1;i<=len;i++){tem[i]=(x*10+a[i])/b;x=(x*10+a[i])%b;}//正常高精除低精的除法int pd=0;for(int i=1;i<=len;i++){if(tem[i]){pd=1;f=i-1;break;}}//去除前导零if(pd){for(int i=f+1;i<=len;i++){if(len-f<maxxlen){break;}if(len-f>maxxlen){for(int j=f+1;j<=len;j++){maxx[j]=tem[j];}maxxlen=len-f;break;}if(len-f==maxxlen&&tem[i]>maxx[i]){for(int j=f+1;j<=len;j++){maxx[j]=tem[j];}maxxlen=len-f;break;}if(len-f==maxxlen&&tem[i]<maxx[i]){break;}}}//比较maxx和tem的大小 } int main(){scanf("%d",&n);scanf("%d%d",&sx,&sy);for(int i=1;i<=n;i++){scanf("%d%d",&q[i].l,&q[i].r);}sort(q+1,q+1+n,cmp);for(int i=0;sx;i++){s[i]=sx%10+'0';sx/=10;}len=strlen(s);for(int i=1;i<=len;i++) a[i]=s[i-1]-'0';for(int i=1;i<=len;i++) fa[i]=s[len-i]-'0';for(int i=1;i<=n;i++){divv(fa,q[i].r);mult(a,q[i].l);//这里乘除的次序要注意一下for(int j=1;j<=len;j++) fa[j]=a[len+1-j];}int pd=0;for(int i=f+1;i<=maxxlen+f;i++){if(maxx[i]){pd=1;break;}}if(pd==0){cout<<0;system("pause");return 0;}//如果最后结果是0的话得特判 不然下面输出不了for(int i=f+1;i<=maxxlen+f;i++) cout<<maxx[i];system("pause");return 0; }