A
给出一个字符串以及长度N和K,
判断字符串能否包含K个回文字符。
题解思路
按题目模拟,寻找有没有足够的回文字符。
AC代码
#include <iostream>
#include <string>
using namespace std;
char s[200];
int main ()
{
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
cin>>s;
if ( k == 0 )
{
cout<<"YES\n";
}else
{
if ( k >= (n+1)/2 )
{
cout<<"NO\n";
continue;
}
int p1 = 0 , p2 = n-1 ,cnt = 0 ;
while(s[p1] == s[p2] && p1 < p2 )
{
p1++;
p2--;
cnt++;
}
if ( cnt >= k)
cout<<"YES\n";
else
cout<<"NO\n";
}
}
return 0;
}
B
给出非负数集合S中的N个数
定义mex为 集合中不存在的非负数的最小值
定义max为集合中存在的数的最大值
可以进行K次操作
每次将 此时的(mex+max)/2放入集合,向上取整。
题解思路
暴力加剪枝
用map映射出现的次数。
当放入集合中的数已经出现时,不会影响之后放入的数,也就是一直放这个数。可以直接剪枝。
当mex等于maxx+1,次数会无限循环加入之前的mex,mex也会自增1,也就是之后每次加的元素都是之前没出现过的。剪枝。
第二种情况是TLE后看样例发现的。
AC代码
#include <iostream>
#include <string>
#include <map>
using namespace std;
map <int ,int > q;
int main ()
{
int t;
cin>>t;
while(t--)
{
q.clear();
int n,k, mex = 0 ,maxx = 0 ;
cin>>n>>k;
for (int i = 1 ; i <= n ; i++ )
{
int p;
cin>>p;
q[p]++;
if ( p > maxx )
maxx = p;
}
while(q[mex])
{
mex++;
}
for (int i = 1 ; i <= k ; i++ )
{
if (q[(mex+maxx+1)/2])
{
break;
}else
{
if ( mex == maxx + 1 )
{
n += (k-i+1);
break;
}
q[(mex+maxx+1)/2]++;
if ( (mex+maxx+1)/2 > maxx )
maxx = (mex+maxx+1)/2 ;
while(q[mex])
{
mex++;
}
n++;
}
}
cout<<n<<"\n";
}
return 0;
}