http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1093
o(︶︿︶)o唉!被一个简单的判断两个字母是否同为大写或小写坑苦了……
题意:有N篇文章,每篇文章只有大写或小写字母,打文章的顺序可以是任意的,但对于任意一篇文章必须完整打完才可以打下一篇文章。求全部打完至少要按几次“Caps Lock键”。
思路:总次数分两部分讨论:一部分是每篇文章内部的大小写转换(不考虑打文章前“Caps Lock键”的状态,仅考虑文章内部有按了一次),另一部分是两篇文章的连接处要按几次“Caps Lock键”。
所有文章的首尾只有4种情况:
情况a:大写开头,大写结尾;
情况b:大写开头,小写结尾;
情况c:小写开头,大写结尾;
情况d:小写开头,小写结尾;
最开始默认为小写(“Caps Lock键”关闭),所以“情况d”不会影响“Caps Lock键”的按键次数,因为只需将满足“情况d”的文章放在最开始打就可以,(下面例子中“大/小写”用“大/小”代替)例如:
[初始小] [小……小] [小……小]……
所以最终“Caps Lock键”还是关闭的(即小写状态)。
相同次数的“情况b”和“情况c”可以构成“情况d”的形式,故可以抵消掉。例如:
[初始小] ……( [小……大] [大……小] )……
当剩下的“情况b”时,剩几个则“Caps Lock键”的按键次数需要+几;
当剩下的“情况c”时,因为“情况c”是以小写字母开头大写字母结尾,所以“第一次”无需按“Caps Lock键”,所以按“Caps Lock键”的次数=剩下的个数-1。
“情况b”(或“情况c”)只要出现一次,“情况a”就不会影响“Caps Lock键”的按键次数,因为在他们的前(或后)打“影响“情况a”的文章就可以,例如:
[初始小] ……[小……大] [小……大] ( [大……大] [大……大] )……
[初始小]……( [大……大] [大……大] ) [大……小] [大……小]……
括号里的内容加不加不影响最终结果。
当“情况b”和“情况c”都没出现时,出现“情况a”则“Caps Lock键”的按键次数需要+1。
这样就OK了~好了,下面看代码:
#include<stdio.h>
#include<ctype.h>//isupper()、islower()
char ip[111];
int main()
{
int n,i;
while(scanf("%d",&n)==1)
{
int a=0,b=0,c=0,sum=0;
for(i=1;i<=n;i++)
{
char *p;
scanf("%s",ip);
p=ip+1;
while(*p)
{
int tmp;
if(*p-*(p-1)>=0)
tmp=*p-*(p-1);
else
tmp=*(p-1)-*p;
if((isupper(*p)&&islower(*(p-1)))||(islower(*p)&&isupper(*(p-1))))
{
sum++;
}
p++;
}
if(isupper(ip[0])&&isupper(*(p-1)))
a++;//dada
else if(isupper(ip[0])&&islower(*(p-1)))
b++;//daxiao
else if(islower(ip[0])&&isupper(*(p-1)))
c++;//xiaoda
// else
// d++;//xiaoxiao
}
if(b>c)
sum+=(b-c);
else if(b<c)
sum+=(c-b-1);
else if(a&&b==0&&c==0)
sum+=1;
printf("%d\n",sum);
}
return 0;
}