A. Gaby And Addition(字典树)

链接:A. Gaby And Addition

选拔比赛的时候没有写出来,下来看了下是字典树,就把字典树 学了,这应该算是我学的第三个字符串算法,他的题型也很有特点。

KMP和哈希就是严格的两个字符串比较,而字典树就是一个字符串和对其他全部字符串同时进行处理,好像也只能把所有字符串映射到一张图上了。总之输入多了或影响大了可以往字典树考虑

回归正题,思路

将所有的数分解为18位(建议字符串输入),从高位到低位依次建立字典树。

可以全部数 更新完毕后再查找(另一个不能找到自己,比较麻烦)。也可以先找该点最大的最小的,再去更新该数,因为答案是一对的,先进的搜不到后进的,但后进的可以搜到先进的,答案是不变的,用的时间会更少

每次选择一个数进行查找,比如这个数是000004234求最小,前面的0每次都优先选择0,依次选择1,2,3,4···9,。4可以优先选择6,7,8,9···3,可以通过%10实现这个数字的选择。

min,max答案即可

代码:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<utility>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
#define fo(a,b) for(int i=a;i<=b;i++)
#define inf 0x3f3f3f3f
#define ll long long
#define M 1000005
#define len 19
int t,n,l,cnt=0;
ll minn=(ll)inf*inf,maxx=0,P[20]={1};
char s[20];
int trie[M*20][12];
inline void query_minn(){
    int p=0;
    ll sum=0;
    for(int i=len-1;i>=0;i--){
        int c=(i>=l)?0:s[i]-'0';
        for(int j=10-c;j<20-c;j++){
            if(trie[p][(j%10)]){
                p=trie[p][(j%10)];
                sum+=P[i]*((c+j)%10);
                break;
            }
        }
    }
    minn=min(sum,minn);
}
inline void query_maxx(){
    int p=0;
    ll sum=0;
    for(int i=len-1;i>=0;i--){
        int c=(i>=l)?0:s[i]-'0';
        for(int j=20-c-1;j>10-c-1;j--){
            if(trie[p][(j%10)]){
                p=trie[p][(j%10)];
                sum+=P[i]*((c+j)%10);
                break;
            }
        }
    }
    maxx=max(sum,maxx);
}
inline void add(){
    int p=0;
    for(int i=len-1;i>=0;i--){
        int c=0;
        if(i>=l) c=0;
        else c=s[i]-'0';
        if(!trie[p][c]) trie[p][c]=++cnt;
        p=trie[p][c];
    }
}
int main(){
    fo(1,len-1) P[i]=P[i-1]*10;
    scanf("%d",&n);
    fo(1,n){
        scanf("%s",s);
        l=strlen(s);
        reverse(s,s+l);
        if(i!=1){
            query_minn();       //查询和该数匹配最小是多少
            query_maxx();       //查询和该数匹配最大是多少
        }
        add();      //最后更新该数
    }
    printf("%lld %lld\n",minn,maxx);
    return 0;
}

基本会使用字典树的话,这题就不算难,时间也够,1e6的数,每个数最坏查找10*18次,1e6*10*18=1.8*1e8

但时间是6000ms

猜你喜欢

转载自blog.csdn.net/m0_58177653/article/details/123717276