做题记录 巧用三目运算符(洛谷 P1098 字符串的展开 NOIP2007提高组)

题目传送门 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这种竞赛里很吃亏
所以我们有必要压缩代码,优化一下
我们理一下题目的逻辑

  1. 判断p3,p3=1执行2,p3=2执行3
  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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值