上海计算机学会11月月赛 乙组题解

本文是上海计算机学会11月月赛乙组题解,涉及字符串、贪心、二分等多种算法。包含四题:T1连接数字需用贪心策略排序;T2桌式足球用二分和贪心求最少操作次数;T3树的匹配用树形动态规划和乘法逆元求解;T4平分子集用状态压缩和折半枚举统计可平分的子集数量。

上海计算机学会11月月赛 乙组题解
本次比赛涉及算法:字符串、贪心、二分、思维、树形动态规划、乘法逆元、状态压缩、折半枚举。

比赛链接https://iai.sh.cn/contest/57

第一题: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;
}

第二题:T2桌式足球

标签:二分、贪心、思维
题意:给定一条数轴上 n n n个球和 m m m个球洞的坐标,球的坐标分别为 x 1 , x 2 , . . . , x n x_1,x_2,...,x_n x1,x2,...,xn,球洞的坐标分别为 p 1 , p 2 , . . . p m p_1,p_2,...p_m p1,p2,...pm。每一轮,可以把所有球整体向左平移一格,或整体右移一格,如果有球经过平移掉入球洞,就会一直待在洞里,后续操作也不会对其有影响,求将所有球落入球洞中,需要的最少操作次数。
1 ≤ n , m ≤ 2 × 1 0 5 , − 1 0 9 ≤ x i , p i ≤ 1 0 9 1≤n,m≤2×10^5,−10^9≤x_i,p_i≤10^9 1n,m2×105,109xi,pi109,且数据保证没有 x i = p j x_i=p_j xi=pj
题解:首先,肯定得给这些球和球洞坐标分别从小到大排序。然后观察样例,发现样例是先把所有球往右移动 1 1 1格,再往左移动 4 4 4格最优。

能够想到最终的最少操作次数肯定是:一直往右、一直往左、先往左再往右、先往右再往左 这四种情况中较小次数的那个。

第一步:先去求出每个球分别往左和往右 遇到的第一个球洞的距离,这个部分我们可以通过二分找到第一个大于 x i x_i xi p j p_j pj坐标(即第 i i i个球右边第一个球洞位置),因为题目中保证没有 x i = p j x_i=p_j xi=pj,找到的 p j − 1 p_{j-1} pj

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值