【贪心】【字典树】Gym - 101466A - Gaby And Addition
生活随笔
收集整理的這篇文章主要介紹了
【贪心】【字典树】Gym - 101466A - Gaby And Addition
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:定義一種無進位加法運算,給你n個正整數,問你取出兩個數,使得他們加起來和最大/最小是多少。
無進位加法運算,其實是一種位運算,跟最大xor那個套路類似,很容易寫出對于每個數字,其對應的最優數字是誰,就對于十叉的字典樹,貪心地盡量往使結果更優越的方向走即可。
#include<cstdio> #include<algorithm> using namespace std; int ch[1000010*20][10],sz; typedef long long ll; ll pw[20]; void Insert(ll x) {int U=0;for(int i=18;i>=0;--i){if(!ch[U][x/pw[i]%10ll]){ch[U][x/pw[i]%10ll]=++sz;}U=ch[U][x/pw[i]%10ll];} } ll qmax(ll x){int U=0;ll res=0;for(int i=18;i>=0;--i){int wei=x/pw[i]%10ll;int k=9;for(int j=9-wei;j>=0;--j,--k){if(ch[U][j]){res+=(ll)k*pw[i];wei=j;goto OUT;}}for(int j=9;j>9-wei;--j,--k){if(ch[U][j]){res+=(ll)k*pw[i];wei=j;goto OUT;}}OUT:U=ch[U][wei];}return res; } ll qmin(ll x){int U=0;ll res=0;for(int i=18;i>=0;--i){int wei=x/pw[i]%10ll;int k=0;for(int j=9-wei+1;j<=9;++j,++k){if(ch[U][j]){res+=(ll)k*pw[i];wei=j;goto OUT2;}}for(int j=0;j<=9-wei;++j,++k){if(ch[U][j]){res+=(ll)k*pw[i];wei=j;goto OUT2;}}OUT2:U=ch[U][wei];}return res; } int n; ll a[1000005]; int main(){//freopen("a.in","r",stdin);ll ans1=0,ans2=9000000000000000000ll;pw[0]=1;for(int i=1;i<=18;++i){pw[i]=pw[i-1]*10ll;}scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%I64d",&a[i]);if(i>1){ans1=max(ans1,qmax(a[i]));ans2=min(ans2,qmin(a[i]));}Insert(a[i]);}printf("%I64d %I64d\n",ans2,ans1);return 0; }轉載于:https://www.cnblogs.com/autsky-jadek/p/8358009.html
總結
以上是生活随笔為你收集整理的【贪心】【字典树】Gym - 101466A - Gaby And Addition的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux任务处理及日志查看常用命令
- 下一篇: 为什么用U盘做启动盘