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

文章讲述了如何解决洛谷P1012问题,即对n个十进制正整数进行重新排列以形成最大数字。提出了一种贪心策略,按字符串字典序从大到小排序,通过举反例证明了这一策略的有效性,最后给出了C++代码实现。

第一题: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;
}
### 问题解析 上海计算机学会 202211月乙组T2题目的大意是:给定一个正整数序列,目标是通过若干次操作将序列中所有数的总和减小到不超过 $S$,每次操作可以选择一个数减1。要求在操作中尽可能少地使用操作次数,找出最少的操作次数。 该问题可以通过贪心策略解决,具体思路如下: - **判断初始条件**:首先计算所有数的总和 $sum$。如果 $sum \leq S$,则无需进行任何操作。 - **优先减少较大的数**:为了使操作次数最少,应优先减少较大的数,因为较大的数减少1所带来的总和减少更大。 - **排序与模拟**:将数组按从大到小排序,依次减少每个数,直到总和满足条件为止。 ### 解法实现 以下是一个可能的实现代码示例: ```python n, S = map(int, input().split()) a = list(map(int, input().split())) sum_total = sum(a) if sum_total <= S: print(0) else: a.sort(reverse=True) operations = 0 for num in a: reduce_amount = min(sum_total - S, num) num -= reduce_amount sum_total -= reduce_amount operations += 1 if sum_total <= S: break print(operations) ``` ### 解法分析 - **时间复杂度**:排序操作的时间复杂度为 $O(n \log n)$,遍历数组的时间复杂度为 $O(n)$,因此总时间复杂度为 $O(n \log n)$。 - **空间复杂度**:额外使用的空间为 $O(1)$,不包括输入数组。 ### 优化与扩展 - **允许选择多个数同时减1**:如果允许每次操作同时减少多个数,则可以通过优先队列(最大堆)来维护当前最大的数,每次操作减少堆顶元素。 - **动态规划解法**:对于某些变种问题,例如要求操作后的数组满足特定条件,可以考虑动态规划解法,但此题的最优解更适合贪心策略。 - **大规模数据优化**:若数据规模较大,可以采用堆结构优化减少操作的选取过程,从而减少时间复杂度。 ### 相关问题 1. 如何解决202211月乙组T2的扩展问题,例如允许选择多个数同时减1? 2. 该题的进阶版本是否存在动态规划解法? 3. 如何优化解法以应对更大的数据规模? 4. 如果操作次数的代价不同,如何调整策略以最小化代价?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值