题目传送门 P1098 字符串的展开
题目很长,仔细审题不难发现:
参数p1,p3会影响输出的内容和顺序,参数p2只会影响输出个数,而要实现输出p2个数我们可以用循环解决,也就是说,p2只是改变循环终止条件,无关紧要。 所以我们只需要花精力去处理p1和p3
先放一个伪代码
//头文件及变量定义均省略
int main(){
scanf("%d%d%d%s",&p1,&p2,&p3,ch);
while(ch[i]){
before=ch[i-1];
after=ch[i+1];
f=ch[i];
if(如果before和after符合条件,进入循环){
if(p3==1){
for(int i=before+1;i<after;i++){
p=j;
if(before是字母,并且p1==1,就大写,不然小写)
else if(p1==3) p='*';
for(k=0;k<p2;k++){
printf("%c",p);
}
}
}
else {
for(int i=after-1;i>before;i++){
代码同上;
}
}
}
else printf("%c",f);
i++;
}
return 0;
}
我们可以看出,这样写就算能过也十分麻烦,而且写完还很难查错,在NOIP这种竞赛里很吃亏
所以我们有必要压缩代码,优化一下
我们理一下题目的逻辑
- 判断p3,p3=1执行2,p3=2执行3
- 顺序输出
- 倒序输出
这样是不是就很明显了?
我们可以用一个三目运算符来优化代码
我放上最终的完整代码
#include<iostream>
#include<cstdio>
#include<cstring>
int p1,p2,p3,i=0,k;
char ch[300],before,after,f,j,p; //ch[]用来存字符串,before after存‘-’前面和后面的字符,p用来输出
int main(){
scanf("%d%d%d%s",&p1,&p2,&p3,ch); //输入
while(ch[i]){ //当ch[i]有值时循环
before=ch[i-1];
after=ch[i+1];
f=ch[i]; //f是当前字符
if(f=='-'&&after>before&&(before>='0'&&after<='9'||before>='a'&&after<='z')){
//判断f是不是符合条件,符合就进入循环
for(p3==1?j=before+1:j=after-1;p3==1?j<after:j>before;p3==1?j++:j--){
//这里就是很巧妙的地方,用三目运算符来优化循环条件
p=j; //p存要输出的那个字符
if(p1==2) p=(p>'a')?p-32:p;
//判断要不要大写,这里也很巧,因为只有小写字母需要转换大写,所以其他一律都是原样
else if(p1==3) p='*'; //不要看漏了这个要求
for(k=0;k<p2;k++){ //根据p2输出个数
printf("%c",p);
}
}
}
else printf("%c",f); //不符合条件的直接输出
i++;
}
return 0;
}
虽然是道水题,但是还是有很多地方值得学习的
共勉
END