课后练习回顾,疑难重点总结(一)
1.计算一个四位数各位相加之后的结果
要想求各位相加之和,就必须先弄明白如何得到每一位的值,再将他们相加在一起。
先假设一个四位数为1234,个位是4,十位是3,百位是2,千位是1。不难看出4是1234整除10后取的余数,不免猜测其他数是否也可以用余数得到。经过多次尝试,发现商可以去掉末尾的数字,而余可以获取末尾的数字。
- 个位:1234%10=4
- 十位:1234/10%10=3
- 百位:1234/100%10=2
- 千位:1234/1000%10=1
举一反三,由此找到规律:假设一个n位数为a,第n位的值为a/10^n%10。
于是定义一个四位数为a,得出各位的值的代码如下所示。
// %表示取余数,/表示整数相除
// qw,bw,sw,gw分别表示千位,百位,十位和个位
int qw=a/1000%10;//千位
int bw=a/100%10;//百位
int sw=a/10%10;//十位
int gw=a%10;//个位
2.判断今年是否为闰年
判断年份是否为闰年有着严格的要求:四年一闰,百年不闰,四百年再闰,即既要满足年份可以被4整除,又不能被100整除,但同时能被400整除的条件。其代码如下所示。
//四年一闰,百年不闰,四百年再闰
//year是“4的倍数但不是100的倍数,或者是400的倍数”
int year = 2022;
String res = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ? "是闰年" :
"不是闰年";
System.out.println(year + res);
此处要明确运算符的优先级:小括号>>单目运算符>>算术运算符>>关系运算符>>逻辑运算符>>条件运算符>>赋值/复合赋值运算符。
3.打印1-10000以内的所有完数
要想判断一个数是否为完数,首先要明白完数的判断标准:所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
比如:
- 6是完数,1*6=6,2*3=6,且1+2+3=6;
- 28也是完数,1*28=28,2*14=28,4*7=28,1+2+4+7+14=28;
其次,因为是要打印1-10000以内所有的完数,所以这里要选择使用循环的方式挨个的判断并打印。判断的方法一般由两种,代码如下所示。
方法一:先找出一个数的真因子,再用其减去所有真因子,判断结果是否为0,如果为0,即为完数,最后遍历打印所有符合条件的数。
for(int i=10000;i>0;i--){
int s=i;
for(int j=i-1;j>0;j--){
if(i%j==0) {
s-=j;
}
}
if(s==0){
System.out.println(i + "是完数");
}
打印结果:
方法二:先找出一个数的真因子,再将其所有真因数相加,判断求和结果是否等于该数本身,如果等于该数,即为完数,最后遍历打印所有符合条件的数。
for(int i=1;i<=10000;i++){
int s=0;
for (int j=1;j<i;j++){
if(i%j==0) {
s+=j;
}
}
if(s==i) {
System.out.println(i + "是完数");
}
打印结果:
举一反三:(相似问题)打印所有的水仙花数
- 水仙花数:一个3位数,每一位上的数字的三次方之和等于它本身
- 如153,1+125+27=153
完整代码如下所示。
for(int n=100;n<1000;n++){
int gw=n%10;
int sw=n/10%10;
int bw=n/100;
if(n==gw*gw*gw+sw*sw*sw+bw*bw*bw){
System.out.println(n);
}
}
输出打印结果:
4. 计算1!+2!+……+10!
本题分两步即可完成:
第一步:求n的阶乘,可以用1*2*……*(n-2)*(n-1)*n来表示。其代码如下所示。
int fac=1;//定义阶乘变量为fac,初始值为fac
for(int i=1;i<=n;i++){//n的值需要定义赋值,不然编译会报错
fac*=i;//fac=fac*i
}
第二步:求阶乘之和。同理,阶乘的和也可以用1!+2!+……+(n-2)!+(n-1)!+n!来表示。其代码如下所示。
int res=0;//定义阶乘之和变量为res,初始值为0
for(int i=1;i<=n;i++){//n必须要赋值定义,不然编译会出错
res+=fac;//res=res+fac
}
二者相结合就是1!+2!+……+n!了,本题只需要将n赋值为10即可。完整代码如下所示。
System.out.println("计算1!+2!+...+10!");
int fac=1;
int res=0;
for(int i=1;i<=10;i++){
fac*=i;
res+=fac;
}
System.out.println(res);
5.猴子吃桃问题
题目:假如一只猴子第一天摘了若干桃子,吃了一半多一个,第二天继续吃了剩下的一半多一 个……到第十天吃了最后一个。问,第一天摘了几个?
遇到复杂计算题先不要慌,可以作图找规律:
天数 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
桃子残余数 | 1 | 4 | 10 | 22 | 46 | 94 | 190 | 382 | 766 | 1534 |
因为已经知道了猴子第十天还剩一个桃子,而每天吃了一半多一个,逆推就是(桃子当天剩余数目+1)*2,所以从第10天开始循环9天便能得到第一天桃子的数目。完整代码如下所示。
int Num = 1 ;//猴子第十天剩余的桃子数
for(int i = 1;i<10;i++) {
Num = (Num+1)*2;
System.out.println("第"+(10-i)+"天的桃子的数目为"+Num);}
打印结果:
举一反三: (相似问题)假如一张纸厚度为0.1mm,玉龙雪山的高度为5596m,将纸对折几次后能到达山的高度?
同样是找规律然后用循环求出最终结果。因为每次对折纸张厚度乘2,所以参考代码如下所示。
long paper=1;
long montain=5596*1000*10;
int count=0;
while (paper<montain){
paper*=2;
count++;
//System.out.println(paper);//显示纸每次对折后的高度
}
System.out.println("需要对折"+count+"次才能达到山的高度 最终高度为"+paper);
输出结果:
6.用*打印菱形
菱形可以看做是上下两个三角形打印出来的,所以做的时候要分上下两部分进行。
上半部分:
假设三角形有五层,自上而下做出如下表格。
层数 | 1 | 2 | 3 | 4 | 5 |
星号个数 | 1 | 3 | 5 | 7 | 9 |
左边空格的个数 | 4 | 3 | 2 | 1 | 0 |
- 由此可知,每层星号个数的规律为:2*层数-1;
- 由此可知,每层左边的空白个数(空格)为:5-层数
其代码如下所示。
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5-i; j++) {
System.out.print(" ");//用空格填充空白
}
for (int k = 1; k <= 2*i-1; k++) {
System.out.print("*");//用星号填充图形
}
System.out.println();//输出结果
}
下半部分:
因为上半的三角形为五层,下半只能是5-1=4层才能完美组合成为一个菱形,且下半三角形与上半相反。
- 同理,每层星号个数的规律为:5-(2*层数-1)=9-2*层数;
- 同理,每层左边的空白个数(空格)为:5-(5-层数)=层数
代码如下所示。
for (int i = 1; i <=4; i++) {
for (int j = 1; j <=i; j++) {
System.out.print(" ");//用空格填补空白
}
for (int k = 1; k <=9-2*i; k++) {
System.out.print("*");//用星号填补图形
}
System.out.println();
}
完整代码输出结果:
举一反三:(相似问题)打印九九乘法表
参考代码如下所示。
System.out.println("九九乘法表:");
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i + "*" + j + "=" + i * j + "\t");
}
System.out.println();
}
输出打印结果: