题目链接:传送门
题意:
给定一个直角三角形的周长,有多少个这样的直角三角形
分析:
设三边长为 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;
}
原文:http://blog.csdn.net/bigbigship/article/details/46592899