其他分享
首页 > 其他分享> > [CF938C] Constructing Tests - 构造

[CF938C] Constructing Tests - 构造

作者:互联网

Description

给定两个正整数 \(n,m(m≤n)\),对于一个 \(n\) 阶 \(0-1\) 方阵, 其任意 \(m\) 阶子方阵中至少有一个元素 \(“0”\),则可以求解这个方阵中的 \(“1”\) 的最大数目。现求解这个问题的逆向问题:已知这个最大数目为 \(X\),求相应的 \(n\) 和 \(m\)。

Solution

设法让每个 \(0\) 被充分地利用

于是 \(n,m,x\) 满足关系

\[n^2-\lfloor\frac n m \rfloor^2=x \]

令 \(t=\lfloor n/m \rfloor\),则

\[(n+t)(n-t)=x \]

枚举 \(x\) 的所有分解 \(x=ab\),那么 \(x\) 可以分解为平方差当且仅当 \(a,b\) 的奇偶性相同,此时

\[n=\frac{a+b} 2, \ t=\frac{a-b} 2 \]

如果我们找到了这个分解 \(n,t\),则只需要存在一个 \(m\) 使得 \(t=\lfloor n/m \rfloor\) 即可,我们只需要假设 \(m=n/t\) 判断一下是否可行即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
int t,x;

signed main() {
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--) {
        cin>>x;
        if(x==0) {
            cout<<1<<" "<<1<<endl;
        }
        else if(x==1) {
            cout<<-1<<endl;
        }
        else {
            for(int a=1;a*a<x;a++) {
                int b=x/a;
                if(a*b!=x) continue;
                if((a^b)&1) continue;
                int n=(a+b)/2,t=(b-a)/2;
                int m=n/t;
                if(t==n/m) {
                    cout<<n<<" "<<m<<endl;
                    goto ok;
                }
            }
            cout<<-1<<endl;
            ok:cout<<"";
        }
    }
}

标签:lfloor,Tests,frac,Constructing,int,cin,rfloor,CF938C,方阵
来源: https://www.cnblogs.com/mollnn/p/12795400.html