Let’s denote a m-free matrix as a binary (that is, consisting of only 1’s and 0’s) matrix such that every square submatrix of size m × m of this matrix contains at least one zero.
Consider the following problem:
You are given two integers n and m. You have to construct an m-free square matrix of size n × n such that the number of 1’s in this matrix is maximum possible. Print the maximum possible number of 1’s in such matrix.
You don’t have to solve this problem. Instead, you have to construct a few tests for it.
You will be given t numbers x1, x2, …, xt. For every , find two integers ni and mi(ni ≥ mi) such that the answer for the aforementioned problem is exactly xi if we set n = ni and m = mi.
Input
The first line contains one integer t (1 ≤ t ≤ 100) — the number of tests you have to construct.
Then t lines follow, i-th line containing one integer xi (0 ≤ xi ≤ 109).
Note that in hacks you have to set t = 1.
Output
For each test you have to construct, output two positive numbers ni and mi (1 ≤ mi ≤ ni ≤ 109) such that the maximum number of 1’s in a mi-free ni × ni matrix is exactly xi. If there are multiple solutions, you may output any of them; and if this is impossible to construct a test, output a single integer - 1.
Input
3
21
0
1
Output
5 2
1 1
-1
题意:
给出一个n * n的矩阵,让构建一个只包含01的矩阵,使得1的个数最多,并且每个m*m的矩阵至少包括一个0;现在给出1的个数x,让输出n m,如果不存在输出-1
思路:
先倒着想一下,比如给出n m,让你求出矩阵中1的个数最多是多少。
稍微想一下就知道0的个数应该是(n/m)*(n/m),那么1的个数就是(n * n)-(n/m) * (n/m);
那么现在就是判断这个方程等于x,是否有解。
因为方程是一个平方差,所以想到了平方差公式,把这个式子分解成了两个数相乘:
(n+n/m)*(n-n/m)=x
这时可以暴力枚举x的所有因子,进行求解。
假如x的两个因子分别为 a b,a=(n+n/m), b=(n-n/m).
明显:n/m=(a-b)/2;
则 n=a-n/m;
现在知道n以及n/m,求解m。
可以让temp=n/(n/m),判断n/temp是否等于n/m。
如果相等直接输出n temp,否则这两个因子没有解。
代码:
//#include<bits/stdc++.h>
#include<stdio.h>
#include<vector>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
typedef long long ll;
using namespace std;
const int inf=0x3f3f3f3f;
typedef pair<int,int>p;
const int N=210000;
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
ll x;
scanf("%lld",&x);
if(x==0)
{
printf("1 1\n");
continue;
}
ll flag=0;
for(ll i=1; i<=(ll)sqrt(x); i++)
{
if(x%i==0&&(x/i-i)%2==0&&(x/i-i))
{
ll a=x/i;
ll b=i;
ll quo=(a-b)/2;
ll n=a-quo;
ll m=n/quo;
if(n/m==quo)
{
flag=1;
printf("%lld %lld\n",n,m);
break;
}
}
}
if(flag==0)
printf("-1\n");
}
return 0;
}