(三)、两数交换
在编写程序过程中,经常会涉及两数交换问题。程序中的变量类似于向计算机申请的一个存储空间,现在需要将两个存储空间中的值交换,该怎么处理?比如,现实生活中,瓶A装有酱油,瓶B装有醋,交换A、B两瓶中的液体,通常需要第三个容器temp。我们分三步。
第一步:将瓶A的酱油倒入容器temp中;
第二步:将瓶B的醋倒入瓶A中;
第三步:将容器temp中的酱油倒入瓶B中。
这时我们将两瓶中的液体完成交换,与此类比,“倒入”这个动作相当于计算机程序中的“赋值”,所以在C+中这三个步骤为“temp=A;A=B;B=temp”。上面这个例子只是为了理解方便,实际上,计算机内部两数交换与实际物品交换还有一定差别,感兴趣的读者可以继续查阅相关资料,进一步了解。
实战训练3—三位数转换
问题描述:
输入一个三位数,交换百位与个位上的数字,并输出新的三位数。输入数据保证个位上的数字不为0。
输入格式:
一行一个三位数n。
输出格式:
一行一个新的三位数。
输入输出样例:
输入样例 | 输出样例 |
403 | 304 |
问题分析:
实战训练3和实战训练2类似,实战训练3是把个位和百位上的数字交换,得到一个新数,并输出。解题过程分为5步:输入数据n;进行数位分离得到三位数各个位上的数字;百位上的数字与个位上的数字交换;计算形成新的三位数;输出该三位数。具体程序如写法1所求:
#include<bits/stdc++.h>
using namespace std;
int main() {int n,a, b, c, s, temp;cin>>n;//输一个三位数a=n%10;//得到个位上的数字b=(n/10)%10;//得到十位上的数字c=n/100;//得到百位上的数字//以下三句实现交换temp=a;a=c;c=temp;s=c*100+b*10+a;//得到新的三位数cout<<s<<endl;return 0;
}
本题也可以在得到该三位数各个位上的三个数字后,无需将个位与百位上的数字交换,直接将原个位上的数字乘100,原数十位上的数字乘10,再累加原数在百位上的数字即可得到新的三位数。具体程序如写法2所示:
#include<bits/stdc++.h>
using namespace std;
int main() {int n,a, b, c, s;cin>>n;//输一个三位数a=n%10;//得到个位上的数字b=(n/10)%10;//得到十位上的数字c=n/100;//得到百位上的数字s=a*100+b*10+c;//得到新的三位数cout<<s<<endl;return 0;
}
换一种方式思考,百位上的数字对该三位数贡献了100份,十位上的数字对该三位数贡献了10份,个位上的数字对该三位数贡献了1份,如此我们将百位上的数字减去99份,将个位上的数字加上99份即可得到新的三位数。具体程序如写法3所示。
#include<bits/stdc++.h>
using namespace std;
int main() {int n,a, c, s; cin>>n;//输一个三位数a=n%10;//得到个位上的数字c=n/100;//得到百位上的数字s=n-99*c+99*a;//得到新的三位数cout<<s<<endl;return 0;
}
(四)、格式化输入/输出函数
在之前的学习中,整数的除法是整除,如果需要保留小数点,就需要将数据类型定义为浮点型,比如double。但是面临的新问题也将出现,即计算结果保留小数点后面位数的问题。在题目中涉及小数时,往往要求保留小数点后面2位、4位等,需要格式化的输入/输出语句。
格式化输出函数:
printf("格式控制字符串",输出列表);
格式控制字符串用于指定输出格式,如语句"int a=3; printf("ans=%d",a);",运行结果为"ans=3"。printf语句中"%d"称为格式控制符,决定了最后输出的数据类型和格式。常用的数据类型对应的格式控制符为:int类型为"%d",long long类型为"%lld",float类型为"%f",double类型为"%lf"。
输出列表中数据的输出格式:
%[宽度][.精度][数据类型控制符]
[宽度]可根据题目的需要为该数据提前占位,通常称为“场宽”,如果省略不写,默认为数据实际宽度;[.精度]表示涉及浮点数时,小数点后面保留的位数,例如对于浮点数变量(float类型),输出语句"printf("%.3f",a);"表示将变量a输出时保留小数点后3位。
格式化输入函数:
scanf("格式控制字符串",变量地址列表);
变量地址表示在变量前加取地址符"&",涉及多个变量时,用逗号隔开,而格式控制按照变量的顺序匹配对应的数据类型控制符,例如,在程序中设置了三个变量,int类型变量a,double类量b,long long类型变量c,则输入语句是"scanf("%d%lf%lld",&a,&b,&c);"。使用scanf取数据时,容易犯的一个错误便是没有加取地址符"&",如果不加取地址符,在读取变量时会找不到变量存放的位置,发生运行错误。
实战训练4—与圆相关的计算
时间限制:1S,空间限制:64MB。
问题描述:
给出圆的半径,求圆的直径、周长和面积。
输入格式:
输入包含一个实数(0<r<=10000),表示圆的半径。
输出格式:
输出一行,包含三个实数,分别表示圆的直径、周长和面积,实数与实数之间用空格隔开,每个实数保留小数点后4位。
输入输出样例:
输入样例 | 输出样例 |
3.0 | 6.0000 18.8495 28.2743 |
问题分析:
说明:如果圆的半径是r,那么圆的直径、周长、面积分别为d=2*r, c=2*pi*r, s=pi*r*r,其中pi为3.14159。
r是一个实数,而且pi是一个常量实数,所以在定义变量时的数据类型设置为double。根据题意列表达式计算直径、周长和面积,题目要求输出的每个量保留小数点后4位,所以采用格式化语句输出,即"printf("%.4lf %.4lf %.4lf",d,c,s);"。此外编写程序时,一般输入输出语句要相互匹配,cin语句与cout语句匹配,scanf语句与printf语句匹配,交叉使用可能会出现一些错误。具体程序如下:
#include<bits/stdc++.h>
using namespace std;
const double pi=3.14159;//常量pi的定义
int main() {double r,d,c,s;//定义半径r、直径d、周长c、面积sscanf("%lf",&r);//格式化输入半径rd = 2*r;//计算直径 c = 2*pi*r;//计算周长s = pi*r*r;//计算面积 printf("%.4lf %.4lf %.4lf",d,c,s);//格式化输出return 0;
}