题意:
你得到的是整数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();
- }
- }
-