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

题目链接:传送门

题意:

给定一个直角三角形的周长,有多少个这样的直角三角形

分析:

设三边长为 A,B,C A <= B <= C. A + B + C = L,A^2 + B^2 = C^2

两个方程联立消去C: A + B + sqrt(A^2 + B^2) = l;

B = ( L^2 - 2*L*A )/( 2*L- 2*A )

设t = L - A.  B = L - L^2/( 2*t );

因为 0 < A < L/2;且B为一个正整数。

因此 2*t必定为L^2的一个因子且这个因子必定含有2的倍数。

根据上面的不等式可以解出 sqrt(2)*L < t < L*2

代码如下:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <set>
#include <cstring>
using namespace std;

const int maxn = 1e7+10;

typedef long long LL;

int p[maxn/10],cnt;
bool vis[maxn];
int fac[1000],tot;
int num[1000];

void init(){
    cnt=0;
    memset(vis,0,sizeof(vis));
    for(int i=2;i<maxn;i++){
        if(!vis[i]){
            p[cnt++]=i;
            for(int j=i+i;j<maxn;j+=i) vis[j]=1;
        }
    }
}

void get(LL x){
    tot=0;
    memset(num,0,sizeof(num));
    for(int i=0;i<cnt&&p[i]*p[i]<=x;i++){
        if(x%p[i]==0){
            fac[tot]=p[i];
            while(x%p[i]==0) num[tot]++,x/=p[i];
            num[tot]*=2;
            tot++;
        }
    }
    if(x>1) fac[tot]=x,num[tot++]=2;
}

int ans = 0;
LL n;
set<LL>st;

void dfs(int id,LL val){
    if(id>=tot||val>=2*n) return ;
    if(val>sqrt(2)*n&&val<2*n&&val%2==0)
        st.insert(val);
    if(num[id]>0){
        num[id]--;
        dfs(id,val*fac[id]);
        dfs(id+1,val*fac[id]);
        num[id]++;
    }
    dfs(id+1,val);
}

int main()
{
    init();
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%lld",&n);
        ans = 0;
        if(n%2){puts("0");continue;}
        get(n);
        st.clear();
        dfs(0,1);
        printf("%d\n",st.size());
    }
    return 0;
}


 

你可能感兴趣的:(51nod 1165 整边直角三角形的数量)