题意
(我做了这题才知道caps lock 锁定大小写后,按一下shift键可以输入相反的大小写。)
这题就是给你只有大小写字母的字符串,求最少多少次按键盘。最后caps lock 必须是关闭的。
分析
这题可以模拟也可以dp。
代码
模拟
代码语言:javascript复制#include<cstdio>
#include<cstring>
int t,on,i,ans;
char s[105];
int isU(char a)
{
return a<='Z'&&a>='A';
}
int main()
{
scanf("%d",&t);
while(t--)
{
memset(s,0,sizeof s);
on=i=ans=0;//一开始caps lock关闭
scanf("%s",s);
while(s[i])//处理每个字母
{
if(isU(s[i])&&!on)//如果是大写且caps lock 关闭了
{
ans ;//打开caps lock 或者按一次shift
if(isU(s[i 1]))//如果后面紧接着大写就开启caps lock
on=1;
}
if(!isU(s[i])&&on)//同理
{
ans ;
if(!isU(s[i 1]))
on=0;
}
ans ;//输入当前字母
i ;
}
if(on)//最后使caps lock 关闭
ans ;
printf("%dn",ans);
}
return 0;
}
dp
代码语言:javascript复制#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int t,on,i,ans,n;
char s[105];
int dp[105][2];
int isU(char a)
{
return a<='Z'&&a>='A';
}
int main()
{
scanf("%d",&t);
while(t--)
{
memset(s,0,sizeof s);
memset(dp,0,sizeof dp);
on=i=ans=0;
scanf("%s",s);
//如果s[0]是大写,要关闭状态,那就按shift,再按字母
dp[0][0]=isU(s[0]) 1;
//小写先按字母再按caps lock,大写先caps lock 再按字母
dp[0][1]=2;
n=strlen(s);
for(int i=1;i<n;i )
{
if(isU(s[i])){
//大写字母
//关闭状态,可以由关闭状态按shift键再按字母。或由打开状态按字母再关闭。
dp[i][0]=min(dp[i-1][0],dp[i-1][1]) 2;
//打开状态,可以关闭状态打开再按字母,或打开状态直接按字母。
dp[i][1]=min(dp[i-1][0] 1,dp[i-1][1]) 1;
}else{
//小写字母同理
dp[i][0]=min(dp[i-1][0],dp[i-1][1] 1) 1;
dp[i][1]=min(dp[i-1][0],dp[i-1][1]) 2;
}
}
printf("%dn",dp[n-1][0]);//必须关闭状态
}
return 0;
}