条件分支

这篇文章将总结一下c++的条件分支。

在这之前,我先总结一下c++的判断符。

c++判断符有:>, <, ==, >=, <=, !=。其中,==的用处是判断符号两边是否相等,>=用来判断符号左边是否大于等于右边,<=用来判断符号左边是否小于等于右边,!=用来判断两边是否不等。这里要特别注意,判断相等是用==而不是=,一个等号是用来赋值的。这里你可以在编译器里试一试用=代替==的结果。

汉语中的条件可以总结成:“如果······就;如果不······则”等。而这些在c++中用ifelse来表示。基本结构如下:

if(条件){
    语句1;
}else{
    语句2;
}

或者:

if(条件1){
    语句1;
}else if(条件2){
    语句2;
}else{
    语句3;
}

我们只需要按照格式把东西塞进去就好了。

此外,说到条件又不得不提一下“三目运算符”。三目运算符是为了简化if、else的,但只有部分情况下才能够用上,因此并不常用。三目运算符的格式如下:

表达式1? 表达式2: 表达式3;

举两个例子:

if(a > b){
    max = a;
}else{
    max = b;
}

可以简化为:

maxn = a > b ? a : b;

以及下面这个例子:

if(flag == 1){
    cout << "yes";
}else{
    cout << "no";
}

可以简化为:

cout << (flag == 1 ? "yes" : "no");

*注意这里的括号。

判断的格式是可以扩展的,也就是说一组判断语句可以有多个else if(),但有且只能有一个if(),最多只能有一个else()。像下面这个例子:

if(a % 5 == 0){
	cout << "0";
}else if(a % 5 == 1){
	cout << "1";
}else if(a % 5 == 2){
	cout << "2";
}else if(a % 5 == 3){
	cout << "3";
}else{
	cout << "4";
}

然而就像上面这个例子一样,有时判断语句写起来太过繁琐,所以我们引入一个新的判断语句:switch。switch的用法在一些情况下十分方便。大致结构如下:

switch(变量名){
    case 变量值: 语句1; break;
    case 变量值: 语句2; break;
    default: 语句3; break;
}

switch也是可以扩展的,即你可以多塞几个case进去,但是default最多只能有1个,而且作为switch的结尾使用。当然你也可以不写default。这里我举个例子:

switch(a % 5){
	case 0: cout << "0"; break;
	case 1: cout << "1"; break;
	case 2: cout << "2"; break;
	case 3: cout << "3"; break;
	default: cout << "4"; break;
}

这段语句跟前面那个全是if、else的例子作用是一模一样的,但是代码却精简了不少。

接下来说一说判断语句的嵌套。

判断语句的嵌套,即往判断语句里面再塞些判断语句。例如:

if(flag != 0){
	if(flag2 != 0){
		cout << "no";
	}else{
		cout << "yes";
	}
}else{
	if(flag2 != 0){
		cout << "yes";
	}else{
		cout << "no";
	}
}

学电路的朋友可以看出这段语句其实起到了一个异或门的作用。类似的,switch也可以进行嵌套,这里就不多举例了。

下面再讲一下c++判断语句中表示并列关系的运算符:&&||。&&的意思是“并且”,用来判断两边是否都成立;||的意思是“或者”,用来判断两边是否至少有一边成立。下面是例子:

if((3 > 2) && (3 > 1)){
    cout << "yes" << endl;
}else{
    cout << "no" << endl;
}
if((3 > 2) && (3 > 4)){
    cout << "yes" << endl;
}else{
    cout << "no" << endl;
}

这段话则会得到“yes no”的输出。而如果把段落中&&符号换成||符号,则会得到两个“yes”的输出。

下面是条件分支的一些习题:


今天会下雨吗

Description

你需要写一个程序,读入当前的相对空气湿度 H(0.0≤H≤100.0),气象学家小信认为当相对空气湿度大于 55.4 时,就属于“很可能会下雨”的天气。请根据今天的相对空气湿度,判断今天是否是“很可能会下雨”的天气。

Input

输入一个实数,表示相对空气湿度 H(0.0≤H≤100.0)。

Output

输出为一行,如果 H > 55.4则输出 YES,表示会下雨;否则输出 NO,表示不会下雨。(注意输出全为大写,不要把 YES 写成 Yes 或把 NO 写成 No)

这题只需要简单地对空气湿度进行判断就好了:

#include<iostream>
using namespace std;

int main(){
  float H;
  cin >> H;
  if(H > 55.4) cout << "YES";
  else cout << "NO";
  return 0;
}

*当判断语句只有一条语句时,是可以不打花括号的


求绝对值

Description

在数学中,实数的“绝对值”是一个很有意思的概念,对于小于 0 的实数 n 来说,它的绝对值等于 -n,而对于大于等于 0 的实数来说,它的绝对值等于自身。

接下来,请完成一个程序:对于输入的一个实数 n,输出它的绝对值。

Input

输入包含一个实数 n(−100.0≤n≤100.0)。

Output

输出为一行,为实数 n 的绝对值。

这题就比较经典了。其实只需要判断一下n与零的大小关系:

#include<iostream>
using namespace std;

int main(){
	int n;
	cin >> n;
	
	if(n < 0){
		n = -n;
	}
	
	cout << n;
	return 0;
}

他的名字

Description

小信的老师喜欢用一个字母去记录班上五个同学的名字,他希望你可以在他喊出一个字母的时候告诉他同学的全名。我们知道他记录的字母和同学名字的对应关系:

h 对应 He
l 对应 Li
c 对应 Cao
d 对应 Duan
w 对应 Wang

你的程序将接受到一个字母,如果这个字母有对应的同学名字,则你需要将这个字母对应的同学的名字输出出来。如果这个字母没有对应的同学名字,则输出 Not here。

注意输出时所有字母大小写要与要求完全一致。

Input

输入包含一个字符 x。

Output

输出为一行。如果输入的字母有对应的同学名字,则你需要将这个字母对应的同学的名字输出出来。如果这个字母没有对应的同学名字,则输出 Not here。

请注意,输出的大小写和符号必须完全一致。

这题难度也不大,但是用switch写要精简许多:

#include<iostream>
using namespace std;

int main(){
  char x;
  cin >> x;
  
  switch(x){
    case 'h': cout << "He"; break;
    case 'l': cout << "Li"; break;
    case 'c': cout << "Cao"; break;
    case 'd': cout << "Duan"; break;
    case 'w': cout << "Wang"; break;
    default: cout << "Not here"; break;
  }
  return 0;
}

7的倍数

Description

如果一个数既是 7 的倍数又不能被 2 整除,那么我们称之为 7 的奇倍数。你的程序会读入一个正整数 n,请你判断一下 n 是否是 7 的奇倍数。

Input

输入包含一个正整数 n(0≤n≤100)。

Output

输出为一行,如果输入的正整数 n 是 7 的奇倍数,则输出 YES,否则输出 NO。

这题只需要把题目读懂,然后写代码就行了:

#include<iostream>
using namespace std;

int main(){
  int n;
  cin >> n;
  
  if(n % 7 == 0 && n % 2 != 0) cout << "YES";
  else cout << "NO";
  return 0;
}

面积问题

Description

小信的老师准备和很多个口袋,每个口袋里面有两张纸条。

第一张纸条上说明了我们将要面对的是一个怎样的图形(可能是三角形,也可能是矩形)
第二张纸条上说明了两条边的长度 m 和 n(分别对应三角形的底和高,或者矩形的长和宽)

小蒜会从口袋中随机挑一个,并把纸条上的信息给你,让你的程序计算出图形的面积。

Input

输入包含两行。输入的第一行为一个字符,只可能是 r 或 t。如果是 r 则表示我们要计算面积的图形是一个矩形;如果是 t 则表示我们要计算面积的图形是一个三角形。

输入的第二行为两个实数,m 和 n。分别对应三角形的底和高(或对应矩形的长和宽)(0.0<m≤100.0)。

Output

输出为一行,为目标图形的面积。

这道题需要对r和t进行一下判断,然后分别对应圆和三角形的公式。代码如下:

#include<iostream>
using namespace std;

int main(){
  char ch;
  double m, n;
  cin >> ch >> m >> n;
  
  double ans;
  if(ch == 't') ans = m * n / 2;
  else ans = m * n;
  cout << ans << endl;
  return 0;
}

四位数中有偶数吗

Description

请你通过程序设计,判断一下对于任意一个给定的四位正整数,其中是否存在一个数位上是偶数(提示:偶数是除以 2 余数为 0 的数)。

Input

输入包含一个四位正整数 n(1000≤n≤9999)。

Output

输出为一行,如果 n 的千位、百位、十位、个位中的任何一个为偶数,则输出 YES,否则输出NO。

这道题需要你灵活地运用/和%符号,将n的各个位数提取出来。大致方法为:提取个位,n % 10;提取十位,n / 10 % 10;提取百位,n / 100 % 10;提取千位,n / 1000。多思考就能懂啦!代码如下:

#include<iostream>
using namespace std;

int main(){
	int n;
	cin >> n;
	
	int a, b, c, d;//分别为各位,十位,百位和千位
	a = n % 10, b = n / 10 % 10, c = n / 100 % 10, d = n / 1000;
	if(a % 2 == 0 || b % 2 == 0 || c % 2 == 0 || d % 2 == 0){
		cout << "YES";
	}else{
		cout << "NO";
	}
	return 0;
}

递归的做法如下:

#include<iostream>
using namespace std;

bool check(int);//声明函数
int main(){
  int n;
  cin >> n;
  
  if(check(n)) cout << "YES";
  else cout << "NO";
  return 0;
}
bool check(int n){
  if(n % 2 == 0) return true;
  if(n >= 10) check(n / 10);//递归调用
  else return false;
}

提一下这里的布尔类型(bool)。布尔类型是一种占内存很小的变量,但是它的值只能为两种情况:1true)和0false),通常会用到判断语句中。


日期的合法性

Description

测试程序将随机给你一个空格分隔了年、月、日的日期(其中的数字都是没有前导零的,也就是说7不会被写成07)。你将需要判断这个日期在我们的公历体系内是否真实存在。如果存在则输出YES,否则输出NO(注意输出的字母都一定是大写字母)。

测试程序给出的测试输入数据中,年、月、日都是正整数(也就是大于零的整数),均不大于 3000。

已知,一年有 1 月到 12 月,共 12个不同的月份;其中 1 月、3 月、5 月、7 月、8 月、10 月、12 月有 31个合法的日,分别为 1 日到 31 日;4 月、6 月、9 月、11 月有 30个合法的日,分别为 1 日到 30 日。对于闰年,2 月有 29个合法的日,分别为 1 日到 29 日;对于平年(不是闰年的年称为平年),2 月有 28 个合法的日,分别为 1 日到 28日。

对于不大于 3000 年的年份,闰年遵循如下规律:

非整百年,能被 4 整除的为闰年。
整百年,能被 400 整除的是闰年。

之后呢,你需要做很多的判断,会嵌套地用到我们已经学的if...else...的结构。你将需要:

判断输入日期中的月份是不是合法的月份(这里特殊情况最少,建议第一层先判断);
针对每个月的日数判断输入日期中日的合法性;
注意抓住特殊的 2 月,在里面讨论年的问题(看是不是闰年);
对于闰年,允许 29 日的存在
对于非闰年不能允许 29 日的存在。

Input

输入3个数,分表表示某个日期的年、月、日。

Output

判断这个日期是否存在,如果存在输出“YES”,否则输出“NO”。

这题对判断语句使用的考察比较深,需要用到非常多的if/else语句,所以我们不妨写一个用来判断的函数:

#include<iostream>
using namespace std;

bool check(int, int, int);
int main(){
  int y, m, d;
  cin >> y >> m >> d;//年月日
  
  if(check(y, m, d)) cout << "YES";//调用函数check
  else cout << "NO";
  return 0;
}
bool check(int y, int m, int d){
	if(m < 1 || m > 12) return 0;//月是否合法
	if(d < 1 || d > 31) return 0;//日是否合法
	if(m == 2 && d > 29) return 0;//不管平年还是闰年,2月天数都不能超过29
	if((m == 4 || m == 6 || m==9 || m == 11) && d > 30) return 0;//对30天的月进行判断
	if(((y % 100 != 0 && y % 4 != 0) || (y % 100 == 0 && y % 400 != 0)) && m == 2 && d 
        >28) return 0;//对平年的二月进行判断
  
	return 1;
}

这题主要把逻辑理清楚就好了。


包裹托运

Description

春节快到了,小信和爸爸一起来到邮局,打算给家住外地的爷爷、奶奶家里捎点年货。邮局的阿姨介绍,托运包裹的运费标准是:包裹重量不大于15 公斤时,每公斤6 元;超过 15 公斤后,其超过部分每公斤 9 元。

现已知包裹的重量为 X 公斤,请同学们和小信一起帮助邮局的阿姨计算一下,包裹的运费 Y应为多少元?

Input

输入只有一行,包含一个数值 X(其中1≤X≤100)表示包裹的重量,单位:公斤。

Output

输出只有一行,包含 1个数,表示包裹的运费。

对x和15的大小关系进行判断一下就行了:

#include<iostream>
using namespace std;

int main(){
  int x;
  cin >> x;
  
  int ans;
  if(x <= 15) ans = x * 6;
  else ans = 90 + (x - 15) * 9;
  cout << ans;
  return 0;
}

乘车费用

Description

星期天上午小红乘出租车去本市的奶奶家。出租车计价方案为: 3公里以内(包括 3 公里)起步价是 13 元,超过 3 公里之后按 2.3 元/公里计价,整个乘车途中另加 1 元钱的燃油费。已知:小红到奶奶家的路程为 N 公里,请你计算一下小红到奶奶家的出租车费用是多少元?

Input

输入只有一行,包含 1个整数 N(其中1≤N≤30)表示路程,单位:公里。

Output

输出只有一行,包含 1 个数,表示出租车费用。

这题需要对N和3的大小关系进行判断,算出里程费之后再加上燃油费。代码如下:

#include<iostream>
using namespace std;

int main(){
  int n;
  cin >> n;
  
  double ans;
  if(n <= 3) ans = 14;
  else ans = 14 + (n - 3) * 2.3;
  cout << ans;
  return 0;
}

彩票

Description

大乐透彩票的获奖编码由两位非零数组成。程序根据获奖编码和用户的输入,可以确定用户是否获奖,具体规则为:

如果用户输入的数与获奖编码完全相同,奖金为 100 元
如果用户输入的所有数字匹配获奖编码的所有数字,奖金为 20 元
如果用户输入的数字能够匹配获奖编码的一个数字,奖金为 2 元

程序输入获奖编码和用户的输入,判断用户最终能获得多少奖金。如果没有获奖,则奖金为 0。

Input

你的程序将会接受两个两位整数,分别表示获奖编码和用户的输入。

Output

输出一个整数,表示用户的奖金。

这题看似复杂,但是题目说了输入的数都是两位数,而且每一位都不为0,因此我们可以把每一位都提出来进行判断。但是注意规则的第二条,它看起来与第一条一样,但是第二条每个数的顺序可以不一样,也就是说如果用户输入12,获奖编码为21,这种情况不符合第一条规则但是是符合第二条规则的。代码如下:

#include<iostream>
using namespace std;

int main(){
  int pass,in;
  cin >> pass >> in;
  
  int ans = 0;
  if(pass == in) ans = 100;//用户的输入与获奖编码完全相同
  else{
  	int p[2] = {pass / 10, pass % 10}, i[2] = {in / 10, in % 10};
  	if(p[0] == i[0] || p[0] == i[1]) ans += 2;匹配一个数字加2元
  	if(p[1] == i[1] || p[1] == i[0]) ans += 2;
  	if(ans == 4) ans = 20;若每个数字都能匹配,奖金变为20
  }
  cout << ans;
  return 0;
}

这里用到了数组。数组就是用来存许多个排在一条线上的数据的,声明数组的方法为:变量类型 数组名[大小]。其中大小必须是整数,而且放在主函数外定义时大小必须为一个常数。但是如果开一个大小为n的数组,数组的下标会是0~n - 1而不是1~n。在访问数组的某个变量时只需要写上:数组名[下标]就可以访问这个下标对应的变量的值了。

这里还有一种特殊的运算:+=。ans += 2是等同于ans = ans +2的,用+=十分的简洁。同理,-=,*=,/=也是这样的。特殊地,当+= 1或者-= 1时,可以直接用++和--来代替。


生肖

Description

生肖基于 12 年一个周期,每年用一个动物代表——

猴(monkey)、鸡(rooster)、狗(dog)、猪(pig)、鼠(rat)、牛(ox)、虎(tiger)、兔(rabbit)、龙(dragon)、蛇(snake)、马(horse)或者羊(sheep)。

已知 1900 属鼠,对于程序输入的年份,输出年份对应的生肖单词。

Input

输入一个整数 year,表示年份(1≤year≤9999)。

Output

输出一个单词,表示生肖。

题目中告诉了1900属鼠,所以我们将1899定义为一个常量,再用输入的年份减去1899再对12取余,然后分情况输出就可以了。

代码如下:

#include<iostream>
using namespace std;

const int be = 1899;//const为修饰符,常量的意思

int main(){
  int year;
  cin >> year;
  
  int ani;
  ani = (year - be) % 12;
  if(ani < 0) ani += 12;//对输入年份小于1899的情况进项处理
  switch(ani){
    case 1: cout << "rat"; break;
      case 2: cout << "ox"; break;
      case 3: cout << "tiger"; break;
      case 4: cout << "rabbit"; break;
      case 5: cout << "dragon"; break;
      case 6: cout << "snake"; break;
      case 7: cout << "hourse"; break;
      case 8: cout << "sheep"; break;
      case 9: cout << "monkey"; break;
      case 10: cout << "rooster"; break;
      case 11: cout << "dog"; break;
      case 0: cout << "pig"; break;//switch是可以不写default的
  }
  return 0;
}

三角形形状

Description

读入三角形的三条边,进行如下的判断:

如果输入值不合法,输出illegal triangle,表示三角形不合法
如果输入值合法,两条较短边的平方和大于最长边的平方,则输出acute triangle,表示锐角三角形
如果输入值合法,两条较短边的平方和等于最长边的平方,则输出right triangle,表示直角三角形
如果输入值合法,两条较短边的平方和小于最长边的平方,则输出obtuse triangle,表示钝角三角形
如果任意两条边的和 大于 第三边,那么输入的三角形就是合法的。

Input

读入三个整数 a,b,c(1≤a,b,c≤100),表示三角形的三条边。

Output

根据情况输出illegal triangle、acute triangle、right triangle、obtuse triangle中的一种。

对于合法,即三角形任意两边之和大于第三边,之差小于第三边:

#include<iostream>//因为要用到sort
#include<algorithm>
using namespace std;

int check(int, int, int);
void print(int);
int main(){
  int a[3];
  cin >> a[0] >> a[1] >> a[2];
  
  sort(a, a+3);//排序函数,两个参数分别为起始位置和结束位置,默认是从小到大排
  
  int ans;
  ans = check(a[0], a[1], a[2]);//判断三角形的四种情况
  print(ans);//对应每种情况的输出
  return 0;
}
int check(int a, int b, int c){
  if(a + b <= c) return 0;//不合法
  if(a * a + b * b > c * c) return 1;//锐角三角形
  if(a * a + b * b == c * c) return 2;//直角三角形
  return 3;//钝角三角形
}
void print(int n){
  switch(n){
    case 0: cout << "illegal triangle"; break;
    case 1: cout << "acute triangle"; break;
    case 2: cout << "right triangle"; break;
    case 3: cout << "obtuse triangle"; break;
  }
}

回文数

Description

读入一个不超过四位的整数,判断它是不是回文数。回文数是指正着看和倒着看一样的数,比如 111、1221 就是回文数,而 1515 不是。

Input

读入一个整数 n(1≤n<10000)。

Output

如果 n 是回文数,则输出YES,否则输出NO。

这题将输入的数从两边向中间进行判断就好了:

#include<iostream>
#include<cstring>//因为需要用到关于字符串的操作
using namespace std;

int main(){
	string n;//声明一个字符串
	cin >> n;
	
	bool flag = true;//判断是否是回文数
	for(int i = 0; i < n.size() / 2; i++){//for循环,基本结构为(变量;条件;命令){语句;}
		if(n[i] != n[n.size() - i - 1]){//从两边向中间判断
			flag = false;
			break;//退出循环
		}
	}
	
	if(flag){
		cout << "YES";
	}else{
		cout << "NO";
	}
	return 0;
}

注意这里用到了循环和字符串,当然不用也是可以做出来的。


昨天和明天

Description

读入一个日期,算出这个日期前一天和后一天的日期。

Input

读入三个整数,分别表示日期的年、月、日。

Output

第一行输出三个用空格分隔的整数,表示前一天的年月日。第二行输出三个用空格分隔的整数,表示后一天的年月日。

对于昨天,只需要将日期减一就可以了;对于明天,只需要将日期加一就可以了。但是还需要判断一下日期是否合法,及时地对月份和年份进行加减的操作。代码如下:

#include<iostream>
using namespace std;

void before(int, int, int);
void after(int, int, int);
bool check(int, int, int);
void print(int, int, int);

int main(){
  int y, m, d;
  cin >> y >> m >> d;
  
  before(y, m, d);
  after(y, m, d);
  return 0;
}
void before(int y, int m, int d){
  bool flag;
  do{
  	d--;
    if(!d){d=31; m--; if(!m){m=12; y--;}}
    flag = check(y, m, d);
    if(flag) print(y, m, d);
  }while(!flag);//do-while的作用是先执行一次括号里的操作,再判断是否继续循环
}
void after(int y, int m, int d){
  bool flag;
  do{
  	d++;
    if(d == 32){ d = 1; m++; if(m == 13){m=1; y++;}}
    flag = check(y, m, d);
    if(flag) print(y, m, d);
  }while(!flag);
}
bool check(int y, int m, int d){
  if(y > 3000) return 0;
  if(m < 1 || m > 12) return 0;
  if(d < 0 || d > 31) return 0;
  if(m == 2 && d > 29) return 0;
  if((m == 4 || m == 6 || m == 9 || m == 11) && d > 30) return 0;
  if(y % 4 != 0 && m == 2 && d > 28) return 0;
  return 1;
}
void print(int y,int m,int d){
  cout << y << " " << m << " " << d << endl;
}

猜你喜欢

转载自blog.csdn.net/qq_35436309/article/details/81085880