直角三角形周长

题目链接:https://www.cupacm.com/newsubmitpage.php?id=1094
这是一道非常典型的枚举题目,以下会一步一步分析如何对枚举进行优化。

题目描述

一个直角三角形的周长是120的话,那么它的三边可以是20,48,52,或者24,45,51,还有30,40,50,有3种不同的解。现在你想知道如果给定一个直角三角形的周长,那么这个周长最多能有多少解呢?假设边长为整数。

输入

第一行一个TTT,表示TTT组测试数据。1≤T≤100001\leq T\leq 100001≤T≤10000
每组测试数据占一行仅含一个整数AAA。0≤A≤1000000\leq A\leq 1000000≤A≤100000

输出

根据每组测试数据请求出以整数A为周长的直角三角形的个数。(边长都为整数的直角三角形且周长为整数A)

样例输入

2
12
120

样例输出

1
3

题解

这是一道非常典型的枚举题目,以下会一步一步分析如何对枚举进行优化,希望能对其他枚举问题有所启发。

0.三重循环

看到这道题,首先会想到枚举三条边,如果能符合三条边加在一起等于周长,符合勾股定理,则满足条件并计数。

//TLE
ans = 0;
cin >> l;
for (int i = 1; i < l; i++) {for (int j = 1; j < l; j++) {for (int k = 1; k < l; k++) {if (i + j + k == l && i * i + j * j == k * k) {ans++;}}}
}
cout << ans / 2 << '\n';

毫无疑问,这样最普通的枚举时间超限了。

1.二重循环

现在,做一点优化,指定i≤ji\leq ji≤j,这样可以避免iii与jjj重复枚举(例如345,435是同一个答案)来节约时间,kkk作为斜边,直接通过ijijij和周长便可以计算出kkk,减少一重循环。

//TLE
ans = 0;
cin >> l;
for (int i = 1; i < l; i++) {for (int j = i; j < l; j++) {int k = l - i - j;if (i * i + j * j == k * k) {ans++;}}
}
cout << ans << '\n';

然而,还是TLE。

2.二重循环再优化

首先,我们先对问题进行数学分析:
已知 i+j+k=li+j+k=li+j+k=l , 0&lt;i≤j&lt;k0&lt;i\leq j&lt;k0<i≤j<k ,
通过不等式可以得到 i&lt;l/3i&lt;l/3i<l/3 , j&lt;l/2j&lt;l/2j<l/2 。
在二重循环的基础上,对iii和jjj的范围进行限制

//716ms
ans = 0;
cin >> l;
for (int i = 1; i < l / 3; i++) {for (int j = i; j < l / 2; j++) {int k = l - i - j;if (i * i + j * j == k * k) {ans++;}}
}
cout << ans << '\n';

现在可以通过这道题目了,优化到了700多毫秒的时间。
再抓住两边之和大于第三边的性质,但是仍然需要600毫秒的时间。

//598ms
ans = 0;
cin >> l;
for (int i = 1; i < l / 3; i++) {for (int j = i; j < l / 2; j++) {int k = l - i - j;if (k < i + j && i * i + j * j == k * k) {ans++;}}
}
cout << ans << '\n';

那么,还能再优化吗?

3.一重循环

让我们重新回到数学上,2个方程2个未知数,我们可以轻松求出jjj关于iii、lll的表达式。
已知 i+k+j=li+k+j=li+k+j=l , i2+j2=k2i^{2}+j^{2}=k^{2}i2+j2=k2 ,
可以解得 j=l−l2/(2l−2i)j=l-l^{2}/(2l-2i)j=l−l2/(2l−2i) 。
通过数学方法,我们获得了j的表达式,再判断一下j小于l并且j是整数便可。
这样的程序只有一重循环了,我们将程序从一开始的超时优化到了1ms,这是枚举常见的优化方法——利用数学方法来减少循环次数。

//1ms
ans = 0;
cin >> l;
for (int i = 1; i < l / 3; i++) {double j = l - (double) l * l / (2 * l - 2 * i);if (i < j && j - (int) j < 1e-5) {ans++;}
}
cout << ans << '\n';

总结

枚举通过穷举,来遍历一个问题的所有可能,找到符合条件的可能,便是答案。
在枚举时,应当使用数学方法来对问题进行优化,可以有效减少枚举的次数,提高算法的效率。

[CUPOJ] 直角三角形周长 枚举优化 题解相关推荐

  1. 【牛客每日一题】 4.13 Xorto(前缀异或和,枚举优化/映射)

    链接:https://ac.nowcoder.com/acm/problem/14247 来源:牛客网 题目描述 给定一个长度为n的整数数组,问有多少对互不重叠的非空区间,使得两个区间内的数的异或和为 ...

  2. 四点之间最短路(spfa+优先队列+枚举优化)UESTC1955喜马拉雅山上的猴子

    喜马拉雅山上的猴子 Time Limit: 1000 MS     Memory Limit: 256 MB Submit Status 余周周告诉我喜马拉雅山上有猴子,他们知道点石成金的方法.我不信 ...

  3. Objective-C 高性能的循环遍历 forin - NSEnumerator - 枚举 优化

    Cocoa编程的一个通常的任务是要去循环遍历一个对象的集合  (例如,一个 NSArray, NSSet 或者是 NSDictionary). 这个看似简单的问题有广泛数量的解决方案,它们中的许多不乏 ...

  4. uva1618 分步枚举优化

    不需要获得所有情况,存在性问题等,遇到多次枚举例如 n^4这种,可以用多次n^2得到大小关系,优化为常数级获取关系,然后依次n^2枚举+常数获取关系,复杂度仍为n^2. 此题:存在性问题,有即可,利用 ...

  5. 枚举 ---- D. Zigzags[ Educational Codeforces Round 94 (Rated for Div. 2)]思维枚举优化4重循环

    D. Zigzags 题目大意:就是给你i<j<k<l并且aj=al&&ai=aki<j<k<l并且a_j=a_l \&\& a_i ...

  6. 2017蓝桥杯C++B:等差素数列(枚举优化)

    二.题目:等差素数列 2,3,5,7,11,13,-.是素数序列. 类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列. 上边的数列公差为30,长度为6. 200 ...

  7. #796. 徐老师的电路安全(暴力枚举优化)

    先预处理出对于某一盏用电设备,能控制它的控制设备的个数. 枚举开关,将这个控制设备的贡献减掉,如果仍然能控制所有用电设备则输出 YES,最后如果都没输出YES,最后就输出NO 代码: #include ...

  8. python【蓝桥杯vip练习题库】ALGO-118连续正整数的和(枚举优化)

    试题 算法训练 连续正整数的和 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 78这个数可以表示为连续正整数的和,1+2+3,18+19+20+21,25+26+27. 输入一个正 ...

  9. 递增三元组蓝桥杯c语言,第九届蓝桥杯_递增三元组(枚举的优化思路)

    给定三个整数数组 A = [A1, A2, ... AN], B = [B1, B2, ... BN], C = [C1, C2, ... CN], 请你统计有多少个三元组(i, j, k) 满足: ...

最新文章

  1. 在微型计算机机箱的面板上,【简评】全侧透快拆设计,迎广101机箱体验
  2. EBS并发管理器启动失败,系统暂挂,在重置计数器之前修复管理程序
  3. vs2008 使用Visual Leak Detector检测内存泄漏
  4. oracle 10g 安装介质,如何从Oracle 10g的安装介质中提取BBED必须的sbbdpt.o和ssbbded.o库文件...
  5. %3c dd%3e html,index.html
  6. 日语学习 (助词 「で」 和「に」 的区别)
  7. 继承ActionSupport类
  8. java 解析中文乱码_解析Java中文乱码的处理方法
  9. 图像坐标球面投影_PostGIS空间数据库SRID背景知识 - 地理坐标系(球面坐标系)和投影坐标系(平面坐标系)...
  10. KVM切换器如何选购
  11. 北京家庭摇号计算机,北京摇号积分计算|2021北京家庭摇号积分怎么算? 北京家庭积分摇号计算 - 有车一族汽车网...
  12. matlab三重积分计算方法,一般区域二重、三重积分MATLAB计算方法
  13. 什么是CLI(命令行界面)、GUI(图形用户界面)、Terminal(终端)、Console(控制台)、Shell、TTY
  14. Linux CentOS7.0 使用root登录桌面
  15. 量子力学在计算机上的应用论文,《浅谈量子力学的发展与利用》-毕业论文.docx...
  16. 子类继承多个父类总结
  17. leetcode 题解 904.水果成篮(Typescript)
  18. orcale 基本語法
  19. Leetcode刷题笔记之445. 两数相加Ⅱ
  20. 计算机网络交换机原理,计算机网络__交换机工作原理

热门文章

  1. 鸿合一体机触屏没反应怎么办_一体机电脑触摸屏没反应怎么办 触摸屏一体机故障解决方法...
  2. [论文笔记]Teaching Machines to Read and Comprehend
  3. 大学操作系统期末考试复习经典计算题快速回顾
  4. 【zz】陈硕:当析构函数遇到多线程──C++ 中线程安全的对象回调
  5. oracle支持utf8字符集,AL32UTF8/UTF8(Unicode)数据库字符集含义
  6. matlab 单位化矩阵,MATLAB数据矩阵单位化,归一化,标准化
  7. Spring Data JPA手动管理事务
  8. Altium Designer 19.1.18 - 隐藏某一个网络的飞线
  9. python表示整数的点称为整点_礼行天下 仪动职场智慧树网课答案
  10. lanyu 激活idea