洛谷月赛 LGR-099 div.2 A-B题解
前两天没事刷了下洛谷月赛div2,发现打卡题难度都提高了些,在出题人的帮助下AC了前两题。
题目
- Easy Strings Merging

思路(最容易想到的)
这题很容易就能想到,字符串头只能为0或1。所以我们可以枚举开头0、1,然后查找每一个字符串是否有相同的前缀,如果相同则加入,找不到则换一个。于是,我们可以将每个字符串存进vector中,遍历到符合的就加入,如果此时字符串为空,那么size–,当size==0时说明每个字符串都处理结束了。
注意
在vector中eraser的时间复杂度很大,如果使用会导致后面的测试点TLE(在出题人帮助下发现的)。所以在当前字符串处理结束后,不能直接vector.eraser掉。
#include<bits/stdc++.h>
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e6 + 10;
int n, ans;
int check(string);
int solve(vector<string>, string);
int main() {
io_opt;
cin >> n;
vector<string> vtr(n);
for (int i = 0; i < n; i++) cin >> vtr[i];
if (n == 1) {
ans = check(vtr[0]);
}
else {
ans = max(solve(vtr, "0"), solve(vtr, "1"));
}
cout << ans << endl;
return 0;
}
int solve(vector<string> vtr, string str) {
int size = n;
while (size) {
int sta = 0, en = vtr.size();
for (; sta < en; sta++) {
if(vtr[sta].empty()) continue;
int k = 0;
while (vtr[sta][k] == str.back()) k++;
str += vtr[sta].substr(0, k);
vtr[sta].erase(0, k);
if (vtr[sta].empty()) size--;
}
if (sta == en) {
for(sta=0;sta<en;sta++){
if(!vtr[sta].empty()){
str += vtr[sta][0];
vtr[sta].erase(0, 1);
if (vtr[sta].empty()) size--;
}
}
}
}
return check(str.erase(0, 1));
}
int check(string str) {
int res = 0;
for (int i = 0; i < str.size(); i++) {
if (str[i] == str[i + 1]) res++;
}
return res;
}
- Alice and Bob are playing a Normal Game

思路
Alice和Bob可以对数列在头部或尾部插入一个范围在[-xi,xi]的数字。数组得分由每个元素计算得到,奇数位置加,偶数位置减。所以我们可以得知,若在头部插入一个数字,那么之前数组的每一个元素位置都会向后移动,即为奇偶性相反,那么得分也会相反,若在尾部插入一个数字那么对之前得分没有影响。所以可以理解,每一步操作都可以使数组的变正变负,并且可以加入一个范围在[-xi,xi]的数字。所以最后一部操作的人可以使数组向他期望的方向变换,例如:Alice希望得分大,如果上一步得分为负数,可以在头部插入一个数字使它变为正数。所以题目中的都采取最优操作,即为最后操作的人每次都使得分绝对值最大,另一个人每次都让得分绝对值最小,这样最后操作的人能使得分最大,另一个人能使损失最小。
注意
- 希望绝对值变小要判断ans和xi大小关系,如果
ans <= xi那么可以变成0,而不是单纯的ans - xi
#include<bits/stdc++.h>
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
#define rg register
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 1e6 + 10;
int n,k,t,x;
int main() {
io_opt;
ll ans = 0;
cin >> n >> k;
for(int i=1;i<=n;i++){
cin >> t;
ans += (i % 2 ? t : -t);
}
if(ans < 0) ans = -ans;
int op = k % 2; //记录最后一个人
while(k--){
cin >> x;
ans = (k & 1) ? ((ans > x )?(ans - x): 0):(ans + x);
}
if(!op) ans = -abs(ans);
cout << ans << endl;
return 0;
}
本文解析了洛谷月赛div.2中的两道题目,包括字符串合并问题及Alice和Bob的游戏策略。针对字符串合并问题,提出了枚举开头并查找相同前缀的方法;对于游戏策略问题,则通过分析操作的影响来确定最优解。
485

被折叠的 条评论
为什么被折叠?



