【洛谷】洛谷深基学习记录 第三章 分支结构程序设计

知识积累

关系表达式与逻辑表达式

关系表达式

      在C++中常常能见到被括号括起的式子,里面是两个数字或变量被一个符号连接起来,那样的式子一般是关系表达式,中间的符号是关系运算符。只要按照标准格式写,一整个括号和括号里的式子就相当于一个布尔值,若式子成立,则布尔值为1,若不成立,则布尔值为0,准确来说,就是在关系运算符两边放表达式,就会计算这两边的关系,返回1或者0;

#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a,b;
    cin>>a>>b;
    cout<<(a>b)<<endl;
    cout<<(a<=b)<<endl;
    cout<<(a==b)<<endl;
    cout<<(a!=b)<<endl;
/*  
    double m,n;
    cout<<(fabs(a-b)<1e-6)<<endl;
//浮点数不能直接用==,因为有误差,不会完全相等,
只能说两者的差的绝对值很小,就看作二者相等了。
*/

在比大小问题里,特别需要注意的是,不可以在同一个表达式里同时出现多个大于号或小于号,比如 (a<=b<=c) ,这是不允许的,只能写成 (a<=b&&b<=c)。

       在题目中,关系表达式有时候会很长,这样直接写在cout语句里就显得很麻烦,看起来也很繁琐,所以可以先将关系表达式的布尔值赋给一个整型变量,用 int、char 都可以,但习惯上会定义 bool 型的变量,因为占用字节少,只能表示0和1这两种取值;

#include<iostream>
using namespace std;
int main(){
    int x;
    bool p1,p2;
    p1=x%2==0;//这里将表达式返回的布尔值直接赋给bool型变量p1,不需要加括号;
    p2=x<12;
    cout<<(p1&&p2)<<endl;//cout语句里的表达式就需要加括号;
    return 0;
}

       在一些刁钻的题目里,关系表达式十分复杂,里面包含了各种四则运算符号和关系运算符,但是计算机不是按字面顺序来处理表达式返回布尔值的,计算机的处理会按照特定的顺序进行,也就是遵照一定的优先级,下面表格里的运算符从左到右,优先级从高到低

(   )* 、  /、 %+   -<、  >、   <=、  >===、   !=

逻辑表达式

       在C++中还可以使用一下几种逻辑运算符:

  • 与运算符:&&    判断两个条件是否同时成立;
  • 或运算符:||       判断两个条件是否至少有一个成立;
  • 异或运算符:^    判断两个条件是否刚好一个成立、一个不成立;
  • 非运算符:!      将一个条件取反,若条件返回值是1,则变成0,返回值是0同理;

       在逻辑运算符中,非运算符!的优先级仅次于括号,与运算符&&的优先级高于或运算符||(没有括号掺和的情况下,先处理&&再处理||),或运算符||的优先级和异或运算符^相同,这三个的优先级都排在最后(也就是做完算术运算和关系运算后才轮到它们)。

典例  闰年判断

输入一个年份,判断这一年是否为闰年,如果是就输出1,否则输出0。

分析:被4整除是闰年,被100整除不是闰年,而被400整除又是闰年。基于此,可以这样写,被400整除作为一个表达式,被4整除且不被100整除作为另一个表达式,这两个表达式只要至少有一个成立,就可以判断为闰年。

#include<iostream>
using namespace std;
int main(){
    int year;
    bool p1,p2,p3;
    cin>>year;
    p1=year%400==0;
    p2=year%4==0;
    p3=year%100==0;
    cout<<(p1||p2&&!p3)<<endl;
    return 0;
}

分支语句

if条件语句

if (成立条件表达式) {

        当条件成立时需要执行的语句 ;

}

else if (另一条件成立表达式) {

        这一条件成立时需要执行的语句 ;

}

else {

        当上面条件都不成立时需要执行的语句;

}

       可以没有 else if 和 else,它们的使用视情况而定。

       需要注意的是,if语句是按书面顺序来执行的,若满足了第一个条件语句并执行后,下面的条件就会全部跳过,所以在做题时,不能将范围较大的条件放在上面,而应该从上往下逐渐扩大条件范围

典例 肥胖问题

BMI指数是国际上常用的衡量人体胖瘦程度的一个标准,其算法是m/h^2,其中m是指以kg为单位的体重,h是指以m为单位的身高。

不同体型范围与判定结果如下:

  • 小于 18.518.5:体重过轻,输出 Underweight
  • 大于等于 18.518.5 且小于 2424:正常体重,输出 Normal
  • 大于等于 2424:肥胖,不仅要输出 BMI 值(使用 cout 的默认精度),然后换行,还要输出 Overweight

现在给出体重和身高数据,需要根据 BMI 指数判断体型状态并输出对应的判断。

输入格式

共一行。

第一行,共 22 个浮点数,m,nm,n,分别表示体重(单位为 kgkg),身高(单位为 mm)。

输出格式

输出一行一个字符串,表示根据 BMI 的对应判断。特别地,对于 Overweight 情况的特别处理请参照题目所述。

#include<iostream>
using namespace std;
int main(){
	double m,h,BMI;
	cin>>m>>h;
	BMI=m/h/h;
	if(BMI<18.5)
		cout<<"Underweight"<<endl;
	else if(BMI<24)
		cout<<"Normal"<<endl;
/*如果这一步能执行,那么上一步已经帮我们筛掉了体重过轻的情况,
  这样小于24的只剩下正常体重,这就是条件范围从上往下逐渐扩大,
  而且,这样还能避免出现 18.5<=BMI 的情况出现,
  因为不能直接对浮点数进行相等的比较!*/
	else
		cout<<BMI<<'\n'<<"Overweight"<<endl;
	return 0;
} 

switch条件语句

switch (变量名) {

        case 变量可能的情况1:执行语句1;break

        case 变量可能的情况2:执行语句2;break

        ……

        default : 执行语句n;break

}

       在switch语句里,变量可能的情况只能是确定的常量,确定的常量可以是int型的整数,也可以是char型的字符,但不能是double型或float型的浮点数,若要用浮点数,则应使用多重if嵌套来进行分支判断。

       还需注意,case的执行语句里不能再定义变量或常量!!要定义请在switch之前最开始就定义好。

       另外,若能保证输入数据一定是合法的,那么最后也可以不写default语句。

典例  月份天数

题目描述

输入年份和月份,输出这一年的这一月有多少天。需要考虑闰年。

输入格式

输入两个正整数,分别表示年份 yy 和月数 mm,以空格隔开。

输出格式

输出一行一个正整数,表示这个月有多少天。

#include<iostream>
using namespace std;
int main(){
	int y,m;
	cin>>y>>m;
	switch(m){
		case 1:case 3:case 5:case 7:case 8:case 10:case 12:cout<<31<<endl;break;
		case 4:case 6:case 9:case 11:cout<<30<<endl;break; //case的情况可叠加;
		case 2:if(y%400==0||y%4==0&&y%100!=0)
					cout<<29<<endl;
			   else cout<<28<<endl;break;
		default:break;//无论是case还是default,最后都务必加上break!
	}
	return 0;
}

问号表达式

形式为  S1?S2:S3  ,意思是如果条件S1成立,那么这个表达式的值为S2,否则这个表达式的值为S3。问号表达式的优先级相当低,所以要用问号表达式时,尽量独立一个句子赋值给变量

刷题小得

ASCII的应用  

将字符类型的数字转换为整型数字时,需要减去字符 '0'。

二、习题答案

习题3-1

四个表达式都成立。判断代码如下:

#include<iostream>
using namespace std;
int main(){
	int a=3,b=4,c=5;
	bool p1,p2,p3,p4;
	p1=(a<b||b>c||a>b);
	p2=(a>c||b>a&&c>b);
	p3=(b-a==c-b);
	p4=(a*b-c>a*c-b||a*b+b*c==b*b*(c-a));
	cout<<p1<<" "<<p2<<" "<<p3<<" "<<p4<<endl;
	return 0;
}

习题3-2

第三个表达式不成立,其余都成立。判断代码如下:

#include<iostream>
using namespace std;
int main(){
	int a=1,b=0,c=1;
	bool p1,p2,p3,p4,p5;
	p1=!a||!b;
	p2=(a&&!a)||(b||!b);
	p3=a&&b&&c||!a||!c;
	p4=a&&(b&&c||a&&c);
	p5=!b&&(c&&(a&&(!c||(!b||(!a)))));
	cout<<p1<<" "<<p2<<" "<<p3<<" "<<p4<<" "<<p5<<endl;
	return 0;
}

习题3-3

(1)  x是否为偶数。

x%2==0

(2)  x是否为四位整数。

x>=1000&&x<10000

(3)  x是否为完全平方数。

#include<iostream>
using namespace std;
int main(){
	int x,i;
	cin>>x;
	for(i=0;i<100000000;i++){
		if(i*i*i==x)
			cout<<"x是完全平方数"<<endl;
	}
	return 0;
}

(4)  x是否同时是奇数、完全立方数,而且是三位整数。

#include<iostream>
using namespace std;
int main(){
	int x,i,k=0;
	cin>>x;
	for(i=5;i<10;i++){
		if(x%2==1&&i*i*i==x)
			k=1;
	}
	if(k==1)
		cout<<"x同时是奇数、完全立方数,而且是三位整数"<<endl;
	else
		cout<<"x不同时是奇数、完全立方数和三位整数"<<endl;
	return 0;
}

(5)  x是否是水仙花数(各位数的立方和等于本身的3位整数)。

#include<cstdio> 
#include<iostream>
using namespace std;
int main(){
	char a,b,c;
	int x,y;
	scanf("%c%c%c",&a,&b,&c);
	x=100*(a-'0')+10*(b-'0')+(c-'0');
	y=(a-'0')*(a-'0')*(a-'0')+(b-'0')*(b-'0')*(b-'0')+(c-'0')*(c-'0')*(c-'0');
	if(x==y)
		cout<<"x是水仙花数"<<endl;
	else
		cout<<"x不是水仙花数"<<endl;
	return 0;
}

习题3-4  保留小数新方法

小玉家的电费

收获:输出要保留一位小数,原来的浮点数要乘10加0.5,然后转换为整型,再除以10.0。若要保留两位小数,就可以里面乘100,外面除以100.0,保留n位小数以此类推。

#include<iostream>
using namespace std;
int main(){
	int x;
	double y; 
	cin>>x;
	if(x<=150)
		y=x*0.4463;
	else if(x<=400)
		y=150*0.4463+(x-150)*0.4663;
	else
		y=150*0.4463+(400-150)*0.4663+(x-400)*0.5663;
	cout<<int(y*10+0.5)/10.0<<endl;
	return 0;
}

习题3-5

#include <iostream>
using namespace std;
int main(){
	int x, n;
	cin>>x>>n;
	int d=n/7*5;
	int r=n%7;
	if(r > 0)
	{
		if(r+x==7||x==7)
			r-=1;
		else if(r+x>=8)
			r-=2;\\这两步不是很理解……
	}
	cout<<(d+r)*250<<endl;
	return 0;
}

习题3-6

#include<iostream>
using namespace std;
int main(){
	int a,b,c;
	cin>>a>>b>>c;
	if(a<=b&&a<=c){
		if(a*a+b*b==c*c)
			cout<<a<<"/"<<c<<endl;
		else
			cout<<a<<"/"<<b<<endl;
	}
	else if(b<=a&&b<=c){
		if(b*b+a+a==c*c)
			cout<<b<<"/"<<c<<endl;
		else
			cout<<b<<"/"<<a<<endl;
	}
	else{
		if(c*c+a*a==b*b)
			cout<<c<<"/"<<b<<endl;
		else
			cout<<c<<"/"<<a<<endl;
	}
	return 0;
}

习题3-7

#include<iostream>
using namespace std;
int main(){
	int a,b,c,d,e,f,g,h,i,j;
	int gao,num=0;
	cin>>a>>b>>c>>d>>e>>f>>g>>h>>i>>j;
	cin>>gao;
	gao+=30;
	if(gao>=a) num++;
	if(gao>=b) num++;
	if(gao>=c) num++;
	if(gao>=d) num++;
	if(gao>=e) num++;
	if(gao>=f) num++;
	if(gao>=g) num++;
	if(gao>=h) num++;
	if(gao>=i) num++;
	if(gao>=j) num++;
	cout<<num<<endl;
	return 0;
}

习题3-8

#include<iostream>
using namespace std;
int main(){
	int a,b,c;
	cin>>a>>b>>c;
	if(a-b>=c||a+b<=c||b-c>=a||b+c<=a||a-c>=b||a+c<=b)
		cout<<"Not triangle"<<endl;
	else{
		if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a){
			cout<<"Right triangle"<<endl;
			if(a==b||b==c||a==c)
				cout<<"Isosceles triangle"<<endl;}
		else if(a*a+b*b>c*c&&a*a+c*c>b*b&&b*b+c*c>a*a){
			cout<<"Acute triangle"<<endl;
			if(a==b||b==c||a==c)
				cout<<"Isosceles triangle"<<endl;
			if(a==b&&b==c)
				cout<<"Equilateral triangle"<<endl;}
		else{
			cout<<"Obtuse triangle"<<endl;
			if(a==b||a==c||b==c)
				cout<<"Isosceles triangle"<<endl;
			}
		}
	return 0;	
	}

习题3-9

#include<iostream>
#include<algorithm>
using namespace std;
int a[3];
char A,B,C;
int main()
{
    cin>>a[0]>>a[1]>>a[2];
    cin>>A>>B>>C;
    sort(a,a+3);
    cout<<a[A-'A']<<" "<<a[B-'A']<<" "<<a[C-'A'];
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值