题目大意:输入一个长方形的面积,求有几个不同的长宽组合可以得到这个面积;
题解:
第一种解法和思路
因为,如果我们能够准确得到长方形的一边,另一条边也就已经被确定了;(这个不难理解)
所以我们枚举长方形的第一条边即可;
如何准确得到能够组合为长方形的第一条边?
长方形的面积 = 边长*边长;
那么边长一定是面积的一个因数!
我们在遍历枚举时,只需要判定循环变量i是否为面积的因数(%==0)即可;
那么这样的代码实现如下:
for(int i=1;i<=n;i++){
if(n%i==0) ans++;
}
但是这样,有一个问题;
我们会直接遍历出所有的可能的组合;
那么,如何求得唯一组合呢?
观察规律:
n=6时,所有的组合为:
1*6 2*3 3*2 6*1
我们其实可以发现:其中上对儿和下对儿是重复的,也就是说,我们可以将组合数/2得到唯一组合;
但是
若n=9时,所有组合为:
1*9 3*3 9*1
3是个奇数,无法/2得到整数啊!
我们先来观察,n=9与n=6时,有什么异同?
除了奇数组合和偶数组合;
奇数组合的组合中,会有一个很不同寻常的式子:
3*3
我们观察,3*3等于n本身;
3*3是:3与自身相乘,3的二次幂,3的乘方;
也就是说,只要n有一个乘方,那么我们就可以在组合数/2的基础上+1,或者是在组合数+1再/2!!!
代码:
for(int i=1;i<=n;i++){
if(n%i==0){
cnt++;
}
}
if(sqrt(n) == int(sqrt(n))){
cnt++;
}
cout << cnt/2;
至此,第一种解法完毕;
第二种解法与思路:
我们还是延续上次的思路,但是这次我们要使用一种更加简洁高效的方法;
还是通过规律找合适的解决方法:
n=6 展开:1*6 2*3 3*2 6*1
n=9展开:1*9 3*3 9*1
n=16展开:1*16 2*8 4*4 8*2 16*1
我们会发现,n=9时,恰好有一个式子3*3能够组成一个特殊的长方形;
再往上的算式就重复了;因此我们称该算式为中点;统计从1到这个中点,所有能构成长方形边的个数,即可算出唯一组合数量;
代码:
for(int i=1;i*i<=n;i++){
if(n%i==0){
ans++;
}
}