Codeforces 938C - Constructing Tests

传送门:http://codeforces.com/contest/938/problem/C

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

由原问题可以得到方程:$n^2-\left\lfloor\frac{n}{m}\right\rfloor^2=X\cdots(1)$,于是,对于给定的X,求解不定方程(1)。

令$k=\left\lfloor\frac{n}{m}\right\rfloor$,则$\left\lfloor\frac{n}{k+1}\right\rfloor<\left\lfloor\frac{n}{k}\right\rfloor$时,$\left\lfloor\frac{n}{m}\right\rfloor=k\Rightarrow k\le\frac{n}{m}<k+1\Rightarrow \frac{n}{k+1}<m\le\frac{n}{k}\Rightarrow m=\left\lfloor\frac{n}{k}\right\rfloor$;于是,原方程化为$n^2-k^2=X\Rightarrow (n+k)(n-k)=X\cdots(2)$。

①若X=0,显然n=k,其中的一组解为n=1,m=1;

②若X≠0,则将X分解,设X=a·b(b<a)。

则解不定方程:$u^2-v^2=ab\Rightarrow u=\frac{a+b}{2},v=\frac{a-b}{2}$。

于是,方程(2)可能有解n=u,k=v

于是,当uv均为正整数,且$\left\lfloor\frac{u}{v+1}\right\rfloor<\left\lfloor\frac{u}{v}\right\rfloor$时,方程(1)有解:$n=u,m=\left\lfloor\frac{u}{v}\right\rfloor$。

参考程序如下:

#include <stdio.h>

int main(void)
{
    int t;
    scanf("%d", &t);
    while (t--) {
        int x;
        int n = -1, m = -1;
        scanf("%d", &x);
        if (x == 0) {
            n = 1;
            m = 1;
        }
        else {
            for (int i = 1; i * i < x; i++) {
                int j = x / i;
                if (x == i * j && !((i ^ j) & 1)) {
                    int u = (j + i) / 2;
                    int v = (j - i) / 2;
                    if (u / v - u / (v + 1) > 0) {
                        n = u;
                        m = u / v;
                        break;
                    }
                }
            }
        }
        if (n == -1) printf("-1\n");
        else printf("%d %d\n", n, m);
    }
    return 0;
}

 

posted on 2018-02-19 23:31  SiuGinHung  阅读(557)  评论(0编辑  收藏  举报

导航