D班第一次模拟赛 C题题解

2023-07-21 15:02:47

写不动数据结构了,下午打打D班的模拟赛玩玩。

C. [2023暑假D班第一场模拟赛]爱新撅罗

题面:

小X穿越了,发现自己成为了一个小人,正准备为一位清朝王爷服务。只要好好地服务,王爷就有赏。

一开始,小X的赏赐是 \(a_0\),满足 \(0\le a_0\le 9\)

小X将为王爷服务 \(n\) 次,第 \(i\) 次他有两种方式为王爷服务:

为王爷整理胡子。王爷会在原有赏赐的数字左侧添加一位,添加的数字为 \(a_i\) \((0 \le a_i \le 9)\)

给王爷唱歌。王爷会在原有赏赐的数字右侧添加一位,添加的数字为 \(a_i\)

小X想知道,他最终能获得的最多赏赐是多少。

输入格式

第一行一个整数 \(n\),表示服务的次数。

第二行 \(n+1\)\(0\)\(9\) 的整数,表示\(a_0,a_1,a_2,…,a_n\)\((n\le 10^6)\)

保证a中不全为0。

输出格式

一个数,表示小X取得的最多赏赐。

样例

input

6
0 1 2 3 2 6 4

output

6321024

简化题意:

给定原数位,按顺序给原数补位,可以选择补在前或者补在后,求最后的数的最大值。

思路

考虑贪心和分治。

越靠左的位置越大数就越大,所以考虑对放左侧贪心。

最大且最靠右的一定得放最左,那它后面的数只能放右。

就递归按照这种方法处理前面的数,最后按顺序把数放在右侧即可。

加排序复杂度 \(O(n\log n)\)

注:千万不要让solve()函数返回string然后在中途为了图方便用substr() 分割,常数太大,且单次分割复杂度 \(O(n)\),导致我挂了个点只有75分,用数组就好,数组常数小。

\(Code\)

struct node{
    int id,v;
    inline bool operator <(const node&w)const{
        if(v==w.v)return id>w.id;
        return v>w.v;
    }
}o[1000006];
int n,t=1,a[1000006];
void solve(int r){
    if(r<1)return;
    while(o[t].id>r)t++;
    int x=o[t].id;
    printf("%d",a[x]);
    solve(x-1);
    for(int i=x+1;i<=r;i++)printf("%d",a[i]);
}
int main(){
    n=read();
    for(int i=1;i<=n+1;i++){
        o[i]={i,a[i]=read()};
    }
    sort(o+1,o+2+n);
    solve(n+1);
}
posted @ 2023-09-08 10:27  NBest  阅读(17)  评论(0)    收藏  举报