题目链接:传送门
题意:
给定一个直角三角形的周长,有多少个这样的直角三角形
分析:
设三边长为 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; }