这题WA好几遍才通过,想一想自己的思路确实有问题,下定决心写记录来提醒自己。
题目背景
honoka 有一个只有两个键的键盘。
题目描述
一天,她打出了一个只有这两个字符的字符串。当这个字符串里含有 VK
这个字符串的时候,honoka 就特别喜欢这个字符串。所以,她想改变至多一个字符(或者不做任何改变)来最大化这个字符串内 VK
出现的次数。给出原来的字符串,请计算她最多能使这个字符串内出现多少次 VK
(只有当 V
和 K
正好相邻时,我们认为出现了 VK
。)
输入格式
第一行给出一个数字 n,代表字符串的长度。
第二行给出一个字符串 s。
输出格式
第一行输出一个整数代表所求答案。
输入输出样例
说明/提示
对于 100% 的数据,1≤ n ≤100。
起初看到这个题目,思路是先找到VK的个数,并对VK做一下标记,然后再找第一个V,直接res++,然后break就行了。然而提交之后74,百思不得其解,通过查看讨论别人的提问和解答才明白,原来漏掉了KK的情况,且之前查找VV的情况也有问题。
那么,这道题的整体思路是先找没改变之前的VK,然后再找第一个VV或KK(至多改变一个字符)。
如何查找VK、VV、KK呢?我个人比较喜欢数字,所以我新开了个数组a[N],并在输入字符串的时候对该数组定义,即当字符为V的时候 a[i]=1;当字符为K的时候 a[i]=2。思路:先找没改变之前的VK,找到之后,结果数res++,并且标记VK对应的数组中的值为0,表示用过了;然后再找第一个VV或KK,即找数组中有没有相邻都为1或都为2的,如果有结果数res++,并且break(只能改变一个);最后输出res。
具体代码如下:
#include<iostream>
using namespace std;
const int N=110;
char s[N];
int a[N];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){//输入字符串并定义a数组
cin>>s[i];
if(s[i]=='V')a[i]=1;
else if(s[i]=='K')a[i]=2;
}
int res=0;
for(int i=0;i<n-1;i++){//先找没改变之前的VK(注意临界)
if(a[i]==1&&a[i+1]==2){//如果a数组中存在相邻的1,2序列,更新结果
res++;
a[i]=0;//标记已经找到的VK
a[i+1]=0;
}
}
for(int i=0;i<n-1;i++){//然后再找第一个VV或KK
if((a[i]==1&&a[i+1]==1)||(a[i]==2&&a[i+1]==2)){//如果a数组中存在相邻的1,1序列或2,2序列,更新结果
res++;
break;//最多改变一次,所以如果找到一个就退出循环
}
}
cout<<res<<endl;//输出结果
return 0;
}
(希望对你有帮助)