题目描述
给定 n 和 k,将从 1 到 n 之间的所有正整数可以分为两类:A 类数可以被 k 整除(也就是说是 kk的倍数),而 B 类数不能。请输出这两类数的平均数,精确到小数点后 1 位,用空格隔开。
数据保证两类数的个数都不会是 0。
输入格式
输入两个正整数 n 与 k。
输出格式
输出一行,两个实数,分别表示 A 类数与 B 类数的平均数。精确到小数点后一位。
输入输出样例
输入 #1复制
100 16
输出 #1复制
56.0 50.1
说明/提示
数据保证,1≤n≤10000,1≤k≤100。
思路:
有三种方法:
方法一:
定义两个数组来分类保存,计算出sum1,sum2,定义两个int型变量j,m用于记录数组元素个数和下标。最后简单一除就完事了。
注意的点(全是我踩过的坑):
1.关于定义数组时数组的长度就写输入的n吧,也可以写n的最大值10000,都可以。
2.数组中元素个数不是数组名.length,而是需要一个特定变量来记录。数组名.length在定义数组时已经知道了,它不是我们需要的数组元素的个数。
package 循环结构;
import java.util.Scanner;
public class P5719_shuzu {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[] sz1 = new int[n];
int[] sz2 = new int[n];
int j = 0, m = 0;
double sum1 = 0, sum2 = 0;
for(int i = 1; i <= n; i++) {
if(i%k == 0)
sz1[j++] = i;
else
sz2[m++] = i;
}
for(int i = 0; i < j; i++)
sum1 += sz1[i];
for(int i = 0; i < m; i++)
sum2 += sz2[i];
System.out.printf("%.1f %.1f",sum1/j,sum2/m);
}
}
方法二:
其实在通过for循环分类时,可以直接计算出sum1,sum2,通过两个特定变量j,m来记录元素个数,之后一除,完事。
package 循环结构;
import java.util.Scanner;
public class P5719 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
double sum1=0,sum2=0;
int m=0,j=0;
for(int i = 1; i <= n; i++) {
if(i % k == 0) {
sum1 += i;
m++;
}else {
sum2 += i;
j++;
}
}
System.out.printf("%.1f %.1f", sum1/m,sum2/j);
}
}
方法三:
大佬的思路果然妙!通过for循环进行分类时直接 for(int i = k; i <= n; i += k),得到sum1,再通过等差数列求和公式 Sn=[n(A1+An)]/2 减去sum1得到sum2,元素个数更好说了,sum1的元素个数时 n/k ,sum2的元素个数是 n-n/k 。妙啊,实在妙!
package 循环结构;
import java.util.Scanner;
public class P5719借鉴 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
double sum1=0,sum2=0;
for(int i = k; i <= n; i += k) {
sum1 += i;
}
sum2 = n*(1+n)/2 - sum1;
System.out.printf("%.1f %.1f", sum1/(n/k),sum2/(n-n/k));
}
}
收获:
1.定义变长数组时,数组长度可以是题目要求的数组的最大长度,只要数组长度不小于题目要求,用什么值都可以。数组元素的真实个数(我们想要的元素个数),是需要特地定义一个变量来记录的。
2.不同的解题思路。分类时没必要从1开始,直接for(int i = k; i <= n; i += k)。