题意:
你得到的是整数n,k。构建一个大小为n×n的网格A,由整数0和1组成。应该满足一个非常重要的条件:网格中所有元素的总和正好为k。
我们来定义一下。
Ai,j为第i行和第j列的整数。
Ri=Ai,1+Ai,2+...+Ai,n(对于所有1≤i≤n)。
Cj=A1,j+A2,j+...+An,j(对于所有1≤j≤n)。
换句话说,Ri是网格A的行和,Cj是列和。
对于网格A,让我们定义值f(A)=(max(R)-min(R))2+(max(C)-min(C))2(这里对于一个整数序列X,我们定义max(X)为X中的最大值,min(X)为X的最小值)。
找到任何满足以下条件的网格A。在这样的网格中找到任何一个,对于它来说,f(A)的值是可能的最小值。在这样的表格中,你可以找到任何一个。
输入
输入由多个测试案例组成。第一行包含一个整数t(1≤t≤100)--测试案例的数量。接下来的t行包含测试用例的描述。
对于每个测试案例,唯一的一行包含两个整数n,k(1≤n≤300,0≤k≤n2)。
保证所有测试用例的n2之和不超过105。
输出
对于每个测试案例,首先打印所有表格中f(A)的最小可能值,对该条件的满足。
然后,打印n行,每行包含n个字符。第i行中的第j个字符应该等于Ai,j。
如果有多个答案,你可以打印任何一个。
题解:
题意已经说的很明确了,让(每行最大最小与的差值平方 + 每列最大最小的差值平方)最小
所以我们应构建一个均匀的矩阵,
剩下就是如何构造了
这是其中一种构造方法
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int a[305][305];
void solve()
{
int n,k;
cin >> n >> k;
memset(a,0,sizeof a);
int t = 1;
while(k)
{
for(int i = t;i <= n;i++)
{
if(a[i][i-t+1]==0&&k)
{
a[i][i-t+1] =1;
k--;
}
}
for(int j = 1;j < t;j++)
{
if(a[j][n-t+j+1]==0&&k)
{
a[j][n-t+j+1] = 1;
k--;
}
}
t++;
}
int ans = 0,l1 = n+1,l2 = n+1,r1 = 0,r2 =0;
for(int i = 1;i <= n;i++)
{
int s1 = 0,s2 = 0;
for(int j = 1;j <= n;j++)
{
s1 += a[i][j];
s2 += a[j][i];
}
l1 = min(s1,l1);
r1 = max(s1,r1);
l2 = min(s2,l2);
r2 = max(s2,r2);
}
ans = (r1 - l1)*(r1 - l1)+(r2 - l2)*(r2 - l2);
cout<<ans<<"\n";
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
cout<<a[i][j];
cout<<"\n";
}
}
int main()
{
int t;
cin >> t;
while(t--)
{
solve();
}
}