上海计算机学会 2023年11月月赛 乙组T1 连接数字(字符串 贪心)

第一题:T1连接数字

标签:字符串、贪心
题意:给定 n n n个十进制正整数 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an,将它们重新排列后拼接起来,尽可能地变成一个大数字,输出这个巨大的数字。 ( 1 < = n < = 100000 , 1 < = a i < = 1 0 18 ) (1<=n<= 100000,1<=a_i<=10^{18}) (1<=n<=1000001<=ai<=1018)
题解:洛谷 P1012 拼数(原题),很明显需要给这个序列重新排序,然后输出这个序列。那问题就转变成了,需要按什么规则进行排序,这里需要想一个好的贪心策略。

  1. 假设按数字大小从大到小排序,很明显能举出一个反例: 111 、 9 111、9 1119 1119 < 9111 1119 < 9111 1119<9111
  2. 到这步能比较容易想到以字符串的方式读入,似乎更可行点。按字符串字典序从大到小排序,上面是满足了,但是也能举出反例: 32 、 3 32、3 323 323 < 332 323<332 323<332。因为字符串比较,如果能比较的位都一样,认为长的字符串字典序大。
  3. 然后我们发现题目中更像是拼接的形式,我们会去考虑把两个字符串 a + b a+b a+b拼接,或者 b + a b+a b+a拼接,然后进行比较大小,发现上面的反例都能满足。那我们就认为该贪心策略是对的。贪心策略是否是正确的,很多时候都很难去证明,我们想一道题的贪心策略的时候,多举反例,只要有一个反例,那你当前想的这个策略就是错的,需要想新的贪心策略。(类似 1 、 2 1、2 12

代码

#include <bits/stdc++.h>
using namespace std;

int n;
string s[100005];

bool cmp(string a, string b) {
    return a + b > b + a;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> s[i];
    sort(s + 1, s + 1 + n, cmp);
    for (int i = 1; i <= n; i++) cout << s[i];
    return 0;
}
  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值