【HDU 2577】How to Type
题意
(我做了这题才知道caps lock 锁定大小写后,按一下shift键可以输入相反的大小写。)
这题就是给你只有大小写字母的字符串,求最少多少次按键盘。最后caps lock 必须是关闭的。
分析
这题可以模拟也可以dp。
代码
模拟
#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("%d\n",ans); } return 0; }
dp
#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("%d\n",dp[n-1][0]);//必须关闭状态 } return 0; }
┆凉┆暖┆降┆等┆幸┆我┆我┆里┆将┆ ┆可┆有┆谦┆戮┆那┆ ┆大┆始┆ ┆然┆
┆薄┆一┆临┆你┆的┆还┆没┆ ┆来┆ ┆是┆来┆逊┆没┆些┆ ┆雁┆终┆ ┆而┆
┆ ┆暖┆ ┆如┆地┆站┆有┆ ┆也┆ ┆我┆ ┆的┆有┆精┆ ┆也┆没┆ ┆你┆
┆ ┆这┆ ┆试┆方┆在┆逃┆ ┆会┆ ┆在┆ ┆清┆来┆准┆ ┆没┆有┆ ┆没┆
┆ ┆生┆ ┆探┆ ┆最┆避┆ ┆在┆ ┆这┆ ┆晨┆ ┆的┆ ┆有┆来┆ ┆有┆
┆ ┆之┆ ┆般┆ ┆不┆ ┆ ┆这┆ ┆里┆ ┆没┆ ┆杀┆ ┆来┆ ┆ ┆来┆