A. Entertainment in MAC
题面:
恭喜你,你被硕士援助中心录取了!但是,你在课堂上感到非常无聊,厌倦了无所事事,于是你给自己想了一个游戏。
给你一个字符串 s 和一个 偶 整数 n 。你可以对它进行两种运算:
1、将反向字符串 s 添加到字符串 s 的末尾(例如,如果 s = cpm,那么在执行操作 s = cpmmpc 之后)。
2、将当前字符串 s 倒转(例如,如果 s = cpm,则在执行操作 s = mpc后)。
需要确定在进行精确的 n 操作后,可以得到的词序最小的字符串。请注意,您可以按照任意顺序进行不同类型的运算,
但必须总共进行n 次运算。
思路:
首先你变换的一定是把最小的字符串放在前面,那么如果还有一次的话,就直接翻转添加一个串,这样才能使字典序最小。
如果说,翻转之后也没有现在的小,那么一定是一直翻转偶数次,这样达到了不变的效果,字典序还是最小。
如果说,翻转之后有现在的小,那么一定是翻转奇数次,一直翻转,达到最小字典序的效果,最后一次直接加上翻转的串就可以了。
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
const int N=1e6+10;
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
#define int long long
void solve()
{
int n; cin >> n;
string a; cin >> a;
auto b=a; reverse(b.begin(),b.end());
if(a<=b)
cout << a << endl;
else cout << b+a << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T=1;
cin >> T;
while(T--)
solve();
}
B. Informatics in MAC
题面:
在硕士援助中心,Nyam-Nyam 接受了一项信息学方面的家庭作业。
有一个长度为 n 的数组 a,你想把它分成 k>1 个子段,使每个子段上的 MEX 都等于相同的整数。
请帮助 Nyam-Nyam 找到合适的除法,或者确定不存在合适的除法。
将数组划分为 k 个子数段的定义是 k 对整数 (l1,r1), (l2,r2), …, (lk,rk),使得 l i ≤ r i li ≤ ri li≤ri 和每个 1 ≤ j ≤ k − 1 1≤j≤k−1 1≤j≤k−1,
l j + 1 = r j + 1 _{j+1} = r_{j+1} j+1=rj+1,以及 l 1 = 1 l_1 = 1 l1=1 和 r k = n r_k = n rk=n 。这些对表示子段本身。
数组中的 MEX 是不属于该数组的最小非负整数。
例如
1、数组 [2,2,1] 的 MEX 是 0 ,因为 0 不属于该数组。
2、数组 [3,1,0,1] 中的 MEX 是 2 ,因为 0 和 1 属于数组,而 2 不属于数组。
3、数组 [0,3,1,2] 中的 MEX 是 4 ,因为 0 、1、2 和 3 属于数组,而 4 不属于数组。
思路:
我只需要从左往右和从右往左预处理就可以了,那么对于从左往右预处理的,第i位的值表示数组 1~i 位未出现的最小整数,
那么对于从右往左预处理的,第 i+1 位表示数组 i+1~n 未出现的最小整数。
最后我只要从1-n遍历一遍就可以了,如果出现 b i = c i + 1 b_i=c_{i+1} bi=ci+1