题解 CF169B 【Replacing Digits】

本蒟蒻又双叒叕被爆踩辣!

大水题!!

题目看上去比较高级,,但是只要理解了题,还是很好写的。

题目意思:

给你由n个数字组成的整数a和长度为m的数字序列s,可以任意互换串a和串s的元素,最后求出的a串最大,每个a串只能去一次。


分析:

窝们运用贪心的思想,对于位数更高的数,窝们显然要让他们更大,所以,窝们把s串按从达到小排序,然后再依次对比a串的当前位和s串当前位,因为s串显然要从大到小依次去,所以前面没取的数后面就取不了,(取前面的显然更优。主要看代码就行。正确性的证明在代码后面。

代码:

#include<bits/stdc++.h>

using namespace std;

const int dx[5] = {0, 1, -1, 0, 0};
const int dy[5] = {0, 0, 0, 1, -1};

//#define XRZ
#define int long long
#define maxn 100010
#define maxm
#define ll long long
#define mian main
#define inf 0x3f3f3f3f
#define ls (x << 1)
#define rs (x << 1 | 1)
#define mid (l + r >> 1)
#define debug(x) printf("now here is %d
", x);
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout);
#define Rep(x, a, b) for(int x = a; x <= b; ++ x)
#define Dep(x, a, b) for(int x = a; x >= b; -- x)
#define Next(x, u) for(int i = head[u]; i ; i = e[i].nxt)
char a[maxn], s[maxn];
bool cmp(char x, char y) {return x > y;}//char类型的排序
signed main(){
    scanf("%s%s", &a, &s);//读入a串和是串,
    int n = strlen(a), m = strlen(s), now = 0;//读取长度,now是排完序的s串遍历到的位数。
    sort(s, s + m, cmp);//排序
    Rep(i, 0, n - 1){//遍历a串,看能不能在s串中找到比它更优的数
        if(s[now] > a[i]){//如果s串中存在以为比这更优,那就更新
            a[i] = s[now];//更新
            ++ now;//s串中这位就没了,指针++
        }
    }
    printf("%s", a);//输出
    return 0;
}
//正确性的证明:因为窝们是枚举a串的,所以s串的当前位在前面肯定是无法起到增大答案的作用,或许它放在后面会有用,但是这是数位上的差距,所以放前面显然更优。

ps:请看懂再抄

原文地址:https://www.cnblogs.com/Flash-plus/p/13834308.html