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; }