其他分享
首页 > 其他分享> > CSUSTOJ|你真的会数三角形吗?

CSUSTOJ|你真的会数三角形吗?

作者:互联网

呜呜呜哥哥太厉害了()

CSUST4013|你真的会数三角形吗?

先通过勾股定理(或者三角形相似)列出表达式,最终可以得到:

( 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,DF,res,ll,CE,int,三角形,会数
来源: https://blog.csdn.net/m0_52042974/article/details/119897086