A. Split it!
首先我们可以发现对于这类似于回文串。
- 对于每个子串,其长度大于等于1,因此如果2k+1>n,那么一定不满足
- 对于第k+1个子串,它比较特殊,可以不用与对应的子串构成镜像,因此k等于0的时候一定是满足的
- 在满足长度不存在问题的情况下,我们发现,从1到k这些子串无论如何划分,只要关于 a [ k + 1 ] a[k+1] a[k+1]镜像,那么就一定满足,因此我们只需要枚举s的第一位到第k位即可,只要这些满足回文的性质,那么都能找到一种方法使得序列满足题意。
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
bool solve(string&s,int n,int k)
{
if(k==0){return true;
}
if(2*k+1>n){return false;
}
for(int i=0;i<k;i++)
{
if(s[i]!=s[n-i-1])
{
return false;
}
}
return true;
}
int main() {
int t;
cin>>t;
while(t--)
{
int n,k;
string s;
cin>>n>>k;
cin>>s;
if(solve(s,n,k)){
cout<<"YES"<<endl;
}else
{
cout<<"NO"<<endl;
}
}
return 0;
}
B. Max and Mex
注意数据范围
通过数据范围我们可以发现,这个操作必须是O(1)的,但是感觉数据结构不太可能,那么应该就是有某种结论或者规律。
a=mex(S),b=max(S)
- a<b时,
- a>b时
其实可以看官方题解,比较简单
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
#define x first
#define y second
typedef long long LL;
typedef pair<int,int> PII;
const int N=100003;
int arr[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
if(k==0){
cout<<n<<endl;
continue;}
int a=-1,b=0;
sort(arr,arr+n);
b=arr[n-1];
for(int i=0;i<n;i++)
{
if(arr[i]!=i)
{
a=i;
break;
}
}
if(a==-1){a=n;}
if(b>a)
{
bool flag=false;
for(int i=0;i<n;i++)
{
if(arr[i]==(a+b+1)/2)
{
flag=true;
break;
}
}
if(flag){cout<<n<<endl;}
else{cout<<n+1<<endl;}
}
else
{
cout<<n+k<<endl;
}
}
return 0;
}