直角三角形,三条边的长度都是整数。给出周长N,求符合条件的三角形数量。

 例如:N = 120,共有3种不同的满足条件的直角3角行。分别是:{20,48,52}, {24,45,51}, {30,40,50}。
 输入:
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 50000)
第2 - T + 1行:每行1个数N(12 <= N <= 10^7)。
输出:
输出共T行,每行1个对应的数量。

解法1:所有本原直角三角形(即边为a、b、c,gcd(a,b,c)==1)可表示为两奇数s和t,s>t,gcd(s,t)==1, 边为st,(s*s-t*t)/2,(s*s+t*t)/2
反之,任意符合条件的s,t也可通过这样组成本原直角三角形
所以周长C= s*(s+t) ,对于C<=1e7,发现是s是sqrt级别的,可以s^2暴力求gcd即O(n*gcd复杂度),求出所有在数据范围内的本原直角三角形的周长
那么对于一个周长n,不同的直角三角形必定对应着不同的本原直角三角形,所以本原直角三角形周长必定是n的因子,枚举n的因子,然后统计答案
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef pair<ll,int>pli;
typedef pair<int,int> pii;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 1e7+;
const int mod = 1e9+;
int mi[maxn],use[maxn],ggg[maxn];
void init(int c=maxn-){
int cc=;
for(int i=; i<=c; ++i) {
if(!mi[i])use[++cc]=i,mi[i]=i;
int to=c/i;
for(int j=; j<=cc and use[j]<=to; ++j) {
mi[use[j]*i]=use[j];
if(i%use[j]==) break;
}
}
int u=sqrt(c);
for(int i=;i<=u;i+=){
int to=min(i-,(c-i*i)/i);
for(int j=;j<=to;j+=){
if(__gcd(i,j)==){
++ggg[i*(i+j)];
}
}
}
}
int f[],cnt[],cc;
int d[],gg;
void dfs(int cur,int now){
if(cur>cc){
d[++gg]=now;
}else{
for(int i=;i<=cnt[cur];++i){
dfs(cur+,now);
now*=f[cur];
}
}
}
int solve(int val,int ti){
int res=;
int tmp=val;
cc=;
while(tmp>){
int v=mi[tmp];
f[++cc]=v;
cnt[cc]=;
while(tmp%v==){
++cnt[cc];
tmp/=v;
}
}
gg=;
dfs(,);
for(int i=;i<=gg;++i)
res+=ggg[d[i]];
return res;
}
int main() {
#ifdef local
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
init();
int T;cin>>T;
for(int i=;i<=T;++i){
int val;cin>>val;
if(val&)cout<<<<"\n";
else cout<<solve(val,i)<<"\n"; }
return ;
}
解法2:化式子
  a*a+b*b = c*c
  a+b+c = n
-> a+b+sqrt(a*a+b*b) = n
-> sqrt(a*a+b*b) = n-a-b
-> 两边平方并化简
-> n^2 - 2an = 2bn-2ab
-> b = (n^2-2an)/(2n-2a)
令f = n-a
则 b = n(2n-2a -n)/(2f) = n(2f - n)/(2f) = n- n^2/(2f)
则有2f | n^2
再看适用范围,有
0 < a < n/3
a < b (不会有等于,abc都是整数,a=b,c=sqrt(2)a × )
得到 n > f > 2n/3 -> 2n > 2f > 4n/3
n-f < n-n^2/(2f) -> 2f^2 > n^2 -> 2f > sqrt(2)n > 4n/3
所以 sqrt(2)n < 2t < 2n
当2t确定,a也确定了
所以在n^2的因子中找符合条件的数
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef pair<ll,int>pli;
typedef pair<int,int> pii;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 1e7+;
const int mod = 1e9+;
int mi[maxn],use[maxn],ggg[maxn];
inline int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
void init(int c=maxn-){
int cc=;
for(int i=; i<=c; ++i) {
if(!mi[i])use[++cc]=i,mi[i]=i;
int to=c/i;
for(int j=; j<=cc and use[j]<=to; ++j) {
mi[use[j]*i]=use[j];
if(i%use[j]==) break;
}
}
// int u=sqrt(c);
// for(int i=3;i<=u;i+=2){
// int to=min(i-1,(c-i*i)/i);
// for(int j=1;j<=to;j+=2){
// if(gcd(i,j)==1){
// ++ggg[i*(i+j)];
// }
// }
// }
}
int f[],cnt[],cc;
ll d[],gg;
void dfs(int cur,ll now){
if(cur>cc){
d[++gg]=now;
}else{
for(int i=;i<=cnt[cur];++i){
dfs(cur+,now);
now*=f[cur];
}
}
}
int solve(int val,int ti){
int res=;
int tmp=val;
cc=;
while(tmp>){
int v=mi[tmp];
f[++cc]=v;
cnt[cc]=;
while(tmp%v==){
++cnt[cc];
tmp/=v;
}
cnt[cc]<<=;
}
gg=;
dfs(,);
int l=sqrt()*val,r=val<<;
for(int i=;i<=gg;++i){
ll v=d[i];
if(v&)continue;
if(v>l and v<r)++res;
}
return res;
}
int main() {
#ifdef local
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
init();
int T;cin>>T;
for(int i=;i<=T;++i){
int val;cin>>val;
if(val&)cout<<<<"\n";
else cout<<solve(val,i)<<"\n"; }
return ;
}

发现两种解法的运行速度差不多。。。


51nod 1165 整边直角三角形的数量(两种解法)的更多相关文章

  1. 51nod 1165 整边直角三角形的数量

    1165 整边直角三角形的数量 直角三角形,三条边的长度都是整数.给出周长N,求符合条件的三角形数量. 例如:N = 120,共有3种不同的满足条件的直角3角行.分别是:{20,48,52}, {24 ...

  2. Java描述表达式求值的两种解法:双栈结构和二叉树

    Java描述表达式求值的两种解法:双栈结构和二叉树 原题大意:表达式求值 求一个非负整数四则混合运算且含嵌套括号表达式的值.如: # 输入: 1+2*(6/2)-4 # 输出: 3.0 数据保证: 保 ...

  3. Letter Combinations of a Phone Number:深度优先和广度优先两种解法

    Letter Combinations of a Phone Number Given a digit string, return all possible letter combinations ...

  4. leetcode-91-解码方法(动态规划和递归两种解法)

    题目描述: 一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只包含数字的非空字符串,请计算解码方法的总数 ...

  5. POJ 1157 LITTLE SHOP OF FLOWERS (超级经典dp,两种解法)

    You want to arrange the window of your flower shop in a most pleasant way. You have F bunches of flo ...

  6. Sort List[leetcode] 由归并排序的递归和循环,到本题的两种解法

    归并排序能够有两种思路----top-down 和 bottom-up top-down: 递归实现,将数组分成两半.分别处理.再合并. 伪代码例如以下: split ( A[], l, r) { i ...

  7. POJ 1182食物链(分集合以及加权两种解法) 种类并查集的经典

    题目链接:http://icpc.njust.edu.cn/Problem/Pku/1182/ 题意:给出动物之间的关系,有几种询问方式,问是真话还是假话. 定义三种偏移关系: x->y 偏移量 ...

  8. 【Java面试真题】剑指Offer53.2——0~n-1中缺失的数字(异或、二分两种解法)

    [Java实现]剑指Offer53.2--0~n-1中缺失的数字:面试真题,两种思路分享 前面有另一道面试题[Java实现]剑指offer53.1--在排序数组中查找数字(LeetCode34:在排序 ...

  9. [LeetCode] Validate Binary Search Tree (两种解法)

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

随机推荐

  1. sql使用临时表循环

    code CREATE PROCEDURE sp_Update_Blogger_Blog_ArticleCount AS BEGIN declare @account varchar(); --博主账 ...

  2. 谁是嫌疑犯问题Python枚举法

    原文:https://blog.csdn.net/yunzifengqing/article/details/81941592 问题描述:有6名犯罪嫌疑人A.B.C.D.E.F,已知如下事实: A.B ...

  3. python之数字类型小知识

    数字是表示计数的抽象事物,也是数学运算和推理的基础,所以,生活中数字是生活中无处不在的,那么,在python语言中运用数字有哪些小知识呢,不妨花点时间看一下这篇博文,牢记这些小知识. 整数类型中四种进 ...

  4. 理解Cookie和Session的区别及使用

    资料一: Cookie和Session的区别 共同之处: cookie和session都是用来跟踪浏览器用户身份的绘画方式. 区别: cookie数据保存在客户端,session数据保存在服务端. s ...

  5. linux命令详解——xargs

    1. 简介 之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了xargs命令,例如: find /sbin -perm +700 |ls -l     ...

  6. Linux配置JDK环境

    wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-co ...

  7. 【两种方式】vuex 如何监听页面状态的变化

    由于 Vuex 的状态存储本来就是响应式的,从 store 实例中读取状态最简单的方法,就是在计算属性中返回某个状态. 在 B 页面引入以下代码: computed: { myValue() { re ...

  8. VMware提示此主机支持Intel VT-x,但Intel VT-x处于禁用状态怎么解决

    本文链接:https://blog.csdn.net/weixin_40816738/article/details/90146770 ThinkPad笔记本1.开机按F1或Fn+F1进入BIOS,切 ...

  9. elk快速入门-Logstash

    Logstash1.功能:数据输入,数据筛选,数据输出2.特性:数据来源中立性,支持众多数据源:如文件log file,指标,网站服务日志,关系型数据库,redis,mq等产生的数据3.beats:分 ...

  10. Python: 多进程的分布式进程multiprocessing.managers

    multiprocessing.managers 在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分 ...