洛谷P1080(NOIP2012)國王遊戲——貪心排序與高精度
阿新 • • 發佈:2018-03-09
clas com har hide con iostream printf 分享 lap
題目:https://www.luogu.org/problemnew/show/P1080
排序方法的確定,只需任取兩個人,通過比較與推導,可以得出ai*bi小的人排在前面;
高精度寫的時候犯了些細節錯誤,詳見註釋。
代碼如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 200005 using namespace std; typedef long long ll;//用long long! ll n,ka,kb,ans[MAXN],tmp[MAXN],tmp2[MAXN],c[MAXN];struct N{ ll a,b; }p[1005]; bool cmp(N x,N y) { return x.a*x.b<y.a*y.b; } void chu(ll a[],ll b) { ll x=0; c[0]=a[0]; for(ll i=a[0];i>0;i--)//倒序存儲,正序除 { c[i]=(x*10000+a[i])/b; x=(x*10000+a[i])%b; } while(c[c[0]]==0&&c[0]>0)c[0]--; } void ch(ll a[],ll b) { ll x=0; for(ll i=1;i<=a[0];i++)//倒序乘 { a[i]*=b;a[i]+=x; x=a[i]/10000; a[i]%=10000; } while(x)a[0]++,a[a[0]]=x%10000,x/=10000; } int com(ll a[],ll b[]) { if(a[0]>b[0])return 1; if(a[0]<b[0])return -1; for(ll i=a[0];i;i--)//倒序! if(a[i]>b[i])return 1; return 0; }void print(ll a[]) { // if(a[a[0]]==0)//? // { // printf("1"); // return; // } printf("%lld",a[a[0]]); for(ll i=a[0]-1;i>0;i--) { printf("%lld",a[i]/1000); a[i]%=1000; printf("%lld",a[i]/100); a[i]%=100; printf("%lld",a[i]/10); a[i]%=10; printf("%lld",a[i]); } } int main() { scanf("%lld%lld%lld",&n,&ka,&kb); for(ll i=1;i<=n;i++) scanf("%d%d",&p[i].a,&p[i].b); sort(p+1,p+n+1,cmp); tmp[0]=1;tmp[1]=ka;//壓位 for(ll i=1;i<=n;i++) { memcpy(tmp2,tmp,sizeof tmp); memset(c,0,sizeof c); chu(tmp2,p[i].b); if(com(c,ans)>0)memcpy(ans,c,sizeof c);//必須>0,否則-1也會被算! ch(tmp,p[i].a); } print(ans); return 0; }
這個運行起來有點慢,有些地方寫得不夠好,下面有一篇運行很快的代碼,可以比較看看提速的方法。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int INF=10000; typedef long long ll; ll n,gb,ljc[1005],max,tmp[1005],ans[1005]; char tp[5]; struct Node{ ll a,b,w; }r[1005]; bool cmp(Node x,Node y) { return x.w<y.w; } void chu(ll b) { ll x=0; tmp[0]=ljc[0]; for(ll i=ljc[0];i;i--) { ll s=ljc[i]+x*INF; tmp[i]=s/b; x=s%b; } while(!tmp[tmp[0]]&&tmp[0]>1)tmp[0]--; } bool comp(ll ans[],ll b[]) { if(ans[0]>b[0])return 0; if(ans[0]<b[0])return 1; for(ll i=ans[0];i;i--) { if(ans[i]>b[i])return 0; if(ans[i]<b[i])return 1; } return 0; } void mul(ll a) { ll x=0; for(ll i=1;i<=ljc[0];i++) { ll s=ljc[i]*a+x; x=s/INF; ljc[i]=s%INF; } if(x)ljc[0]++,ljc[ljc[0]]=x;//至多進一位 } int main() { scanf("%lld%lld%lld",&n,&ljc[1],&gb); ljc[0]=1; for(ll i=1;i<=n;i++) { scanf("%lld%lld",&r[i].a,&r[i].b); r[i].w=r[i].a*r[i].b; } sort(r+1,r+n+1,cmp); for(ll i=1;i<=n;i++) { memset(tmp,0,sizeof tmp); chu(r[i].b); if(comp(ans,tmp))memcpy(ans,tmp,sizeof tmp); mul(r[i].a); } printf("%lld",ans[ans[0]]); for(ll i=ans[0]-1;i;i--) { printf("%lld",ans[i]/1000); printf("%lld",ans[i]/100%10); printf("%lld",ans[i]/10%10); printf("%lld",ans[i]%10); } return 0; }View Code
洛谷P1080(NOIP2012)國王遊戲——貪心排序與高精度