得分情况
A题AC
B题AC
C题AC
D题WA
E题不会
补题情况
全部AC
错题分析
D题
题目大意
多组询问。
将给出的长度为 N 字符串划分成 K 组(不必全部分组,但每组中至少有一个字符),使每组字符串均为回文串,且这 K 组字符串中最短的字符串尽可能长。
初次思路
记录字符出现次数,记录相同字符的对数,记录单个字符的个数,并利用那两个数进行判断(
条件换了好几次,都WA掉了)
正解思路
记录字符出现次数,记录相同字符的对数,记录单个字符的个数,并将成对字符平均分成k份,然后将每份的对数*2(初始答案),剩余的劈成两个单独字符,将数量加入单个字符个数中,看是否够每个回文串中心放一个,够则答案+1,最后输出答案
正解代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int vis[200];
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(vis,0,sizeof vis);
int n,k,cnt1=0,cnt2=0;
string s;
scanf("%d %d",&n,&k);
cin>>s;
for(int i=0;i<n;i++){
vis[s[i]]++;
}
for(int i=97;i<=122;i++){
if(vis[i]%2==1){
cnt1++;
}
cnt2+=vis[i]/2;
}
long long ans=(cnt2/k)*2;
cnt1+=2*(cnt2%k);
if(cnt1>=k){
ans++;
}
printf("%d\n",ans);
}
return 0;
}
错误原因
对题目情况的总结不够准确
E题
题目大意
输入n个长度为m的字符串,在输入一个长度也为m的字符串s,把s 拆分成几个长度大于等于2的子串,并且这些子串也是那n个字符串中的一个的字串
正解思路
因为2,3可以凑出大于一的任何整数,所以我们可以只拆长度为2,3的字串,我们可以先将所有长度为2,3的字串都记录下来,然后通过一遍DP将可能的所有情况推出来,最后从后往前记录一种答案
正解代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int ans[200005],st[200005][35],n,cnt=0;
int main(){
int t;
scanf("%d",&t);
while(t--){
cnt=0;
int q;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&st[i][0]);
}
for(int j=1;j<=log2(n);j++){
for(int i=1;i+(1<<j)-1<=n;i++){
st[i][j]=st[i][j-1]&st[i+(1<<(j-1))][j-1];
}
}
scanf("%d",&q);
while(q--){
int k,ll;
scanf("%d %d",&ll,&k);
if(st[ll][0]<k){
ans[++cnt]=-1;
}
else{
int l=ll,r=n;
while(l<r){
int mid=(l+r+1)>>1;
int s=log2(mid-ll+1);
int lm=st[ll][s]&st[mid-(1<<s)+1][s];
if(lm>=k){
l=mid;
}
else{
r=mid-1;
}
}
ans[++cnt]=l;
}
}
for(int i=1;i<=cnt;i++){
printf("%d ",ans[i]);
}
printf("\n");
}
return 0;
}
错误原因
DP能力差。