CSUSTOJ|你真的会数三角形吗?
Posted KaaaterinaX
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSUSTOJ|你真的会数三角形吗?相关的知识,希望对你有一定的参考价值。
呜呜呜哥哥太厉害了()
先通过勾股定理(或者三角形相似)列出表达式,最终可以得到:
(
n
n
n为正方形边长)
∣
D
F
∣
=
n
−
∣
C
E
∣
+
∣
C
E
∣
2
n
|DF|=n-|CE|+\\frac{|CE|^2}{n}
∣DF∣=n−∣CE∣+n∣CE∣2
并且 ∣ D F ∣ , ∣ C E ∣ |DF|,|CE| ∣DF∣,∣CE∣的长度都是整数。
也就是找到有多少个 ∣ C E ∣ < N |CE|<N ∣CE∣<N,并且 ∣ C E ∣ 2 |CE|^2 ∣CE∣2能被 n n n整除。
如果直接暴力,复杂度巨高,肯定会超时,那么考虑优化。
设 k ∗ n = y 2 k*n=y^2 k∗n=y2,找有几个 y y y就是找有几个 k k k使得 k ∗ n k*n k∗n为平方数,并且 k < n k<n k<n。
继续想,如果
n
n
n本身就是一个平方数,那么
k
k
k也是平方数;如果
n
n
n不是平方数,那么考虑让
n
n
n除一个数
w
w
w使其成为平方数。即:
w
∗
n
∗
k
′
=
y
2
w*n*k'=y^2
w∗n∗k′=y2,
k
′
k'
k′也是平方数且
k
′
<
n
w
k'< \\frac{n}{w}
k′<wn,算出范围内
k
′
k'
k′的个数,即
n
w
−
1
\\sqrt{\\frac{n}{w}}-1
wn−1.
ac代码如下,代码很好写,重点是思路。
int main(){
int T;
cin>>T;
while(T--){
ll n;
cin>>n;
ll m=n;
//分解n
ll x=sqrt(n);
ll res=1;
for(int i=2;i<=x;i++){
int cnt=0;
while(n%i==0){
cnt++;
n/=i;
}
if(cnt%2==1){
res*=i;
}
}
if(n!=1){
res*=n;
}
x=sqrt(m/res);
cout<<x-1<<endl;
}
}
以上是关于CSUSTOJ|你真的会数三角形吗?的主要内容,如果未能解决你的问题,请参考以下文章