算法_三元组的数量

简介: {5 3 1}和{7 5 3}是2组不同的等差三元组,除了等差的性质之外,还有个奇妙的地方在于:5^2 – 3^2 – 1^2 = 7^2 – 5^2 – 3^2 = N = 15。

{5 3 1}和{7 5 3}是2组不同的等差三元组,除了等差的性质之外,还有个奇妙的地方在于:5^2 – 3^2 – 1^2 = 7^2 – 5^2 – 3^2 = N = 15。

{19 15 11}同{7 5 3}这对三元组也存在同样的性质:19^2 – 15^2 – 11^2 = 7^2 – 5^2 – 3^2 = N = 15。

这种成对的三元组还有很多。当N = 15时,有3对,分别是{5 3 1}和{7 5 3},{5 3 1}和{19 15 11},{7 5 3}和{19 15 11}。


现给出一个区间 [a,b]求a <= N <= b 范围内,共有多少对这样的三元组。(1 <= a <= b <= 5*10^6)

例如:a = 1,b = 30,输出:4。(注:共有4对,{5 3 1}和{7 5 3},{5 3 1}和{19 15 11},{7 5 3}和{19 15 11},{34 27 20}和{12 9 6}) 

我的解法:

(1)首先为a到b的每个N值设置一个统计量,可以通过数组实现;

(2)三元组由起始值x和等差确定,即 x,x+d,x+2d,我们可以通过统计x和d来求得N,并将相应的统计量+1;

(3)最后统计对应每个N值的三元组数量,即可解题。

但是这样x和d无法枚举,继续:

由上面得(x+2d)^2-(x+d)^2-x^2=-x^2+2dx+3d^2=(3d-x)(x+d)=N;

另设p=3d-x ;   q=x+d; 那么得:p*q=N  ;   d=(p+q)/4; x=(3q-p)/4;

(注:上面在给a = 1,b = 30例子时没有给{0,3,6}与{12,9,6}这对,说明x的起始值应大于0)

所以得出下面四个限制条件:

1) p+q能被4整除;

2) 3q-p大于等于4;(条件1、2能推出3q-p能被4整除:因为3q-p+p+q=4p)

3) a=<p*q<=b

4)p,q是正整数

由上面4个限制条件我们可以通过枚举p、q来计算出相应的N值,将相应的统计量+1;

你是否会想当不同的p、q计算相同N值的时候是否会是同一个三元组?那么我们假设存在这种情况,那么:

x1=(3*q1-p1)/4  ==  x2=(3*q2-p2)/4 ;

d1=(p1+q1)/4    ==  d2=(p2+q2)/4 ;

解得p1==p2; q1==q2

所以说明只有当p、q两个值都相同时才对应同一个三元组,所以通过枚举p、q,利用上面的4个限制条件解题,转换为C++代码为:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <iostream>  
  3. #include <string>  
  4. using namespace std;  
  5. class Test {  
  6. public:  
  7.     static long Count (int   a,int   b){  
  8.         int res=0;  
  9.         int *resA=new int[b-a+1];  
  10.         for(int i=0;i<=b-a;++i)  
  11.             resA[i]=0;  
  12.         for(int p=1;p<=b;++p){  
  13.             int start=p/4+1;          
  14.             int q=4*start-p;  
  15.             int p3=p/3+2;  
  16.             while(q<=b){  
  17.                 int tmp=p*q;  
  18.                 if(tmp>b)break;  
  19.                 if(q>=p3){  
  20.                     if(tmp>=a)  
  21.                         ++resA[tmp-a];  
  22.                 }  
  23.                 q+=4;  
  24.             }  
  25.         }  
  26.         for(int i=0;i<=b-a;++i)  
  27.             res+=resA[i]*(resA[i]-1);  
  28.         res/=2;  
  29.         return res;  
  30.     }  
  31.   
  32. };  
  33. //start 提示:自动阅卷起始唯一标识,请勿删除或增加。  
  34. int main()  
  35. {     
  36.     cout<<Test::Count(1,30)<<endl;    
  37.     return 0;  
  38. }   
  39. //end //提示:自动阅卷结束唯一标识,请勿删除或增加。  

显然复杂度为sum (1/4*b/i),i=1....b,根据调和级数得,O(blogb)

目录
相关文章
|
存储 算法
算法题:4209三元组
**这次周赛只能做出来一道,,,还是太菜 第一道:** 给定 n 个整数三元组 (xi,yi,zi)。 请你判断这些整数三元组是否能够同时满足以下三个条件: 所有 xi 相加之和为 0。 所有 yi 相加之和为 0。
260 0
|
存储 算法
经典算法题每日演练——第二十题 三元组
原文:经典算法题每日演练——第二十题 三元组          我们知道矩阵是一个非常强大的数据结构,在动态规划以及各种图论算法上都有广泛的应用,当然矩阵有着不足的地方就是空间和时间 复杂度都维持在N2上,比如1w个数字建立一个矩阵,在内存中会占用1w*1w=1亿的类型空间,这时就会遇到outofmemory。
1175 0
|
2月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
261 0
|
2月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
200 2
|
3月前
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
226 3
|
3月前
|
存储 编解码 算法
【多光谱滤波器阵列设计的最优球体填充】使用MSFA设计方法进行各种重建算法时,图像质量可以提高至多2 dB,并在光谱相似性方面实现了显著提升(Matlab代码实现)
【多光谱滤波器阵列设计的最优球体填充】使用MSFA设计方法进行各种重建算法时,图像质量可以提高至多2 dB,并在光谱相似性方面实现了显著提升(Matlab代码实现)
162 6
|
2月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
175 8
|
2月前
|
机器学习/深度学习 算法 自动驾驶
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
181 8
|
2月前
|
机器学习/深度学习 算法 数据可视化
基于MVO多元宇宙优化的DBSCAN聚类算法matlab仿真
本程序基于MATLAB实现MVO优化的DBSCAN聚类算法,通过多元宇宙优化自动搜索最优参数Eps与MinPts,提升聚类精度。对比传统DBSCAN,MVO-DBSCAN有效克服参数依赖问题,适应复杂数据分布,增强鲁棒性,适用于非均匀密度数据集的高效聚类分析。