[原题传送门]
题意
给你一个n和一个k,都为整数,需要你设计一个n*n的01矩阵,由0和1组成,该矩阵的和为k 同时规定,称该矩阵为
A
A
A
m
a
x
(
R
)
max(R)
max(R)为该矩阵的行之和最大值,
m
i
n
(
R
)
min(R)
min(R)为行之和的最小值
m
a
x
(
C
)
max(C)
max(C)为该矩阵列之和的最大值,
m
i
n
(
C
)
min(C)
min(C)为列之和的最小值
f
(
A
)
=
(
m
a
x
(
R
)
−
m
i
n
(
R
)
)
2
+
(
m
a
x
(
C
)
−
m
i
n
(
C
)
)
2
f(A)=(max(R)-min(R))^2+(max(C)-min(C))^2
f(A)=(max(R)−min(R))2+(max(C)−min(C))2 要求输出矩阵A的最小f(A)及f(A)最小时的矩阵
A
A
A
思路
由于
f
(
A
)
f(A)
f(A)的计算特性,需要每行每列都平均分到差不多的1 对于矩阵中的1 可以依照以下方式摆放: 先依照对角线摆放,当对角线摆满,下一个放在右上角的顶点,接下来,从第二行第一列开始,平行对角线向下摆,然后再从第一行第n-1列平行对角线向下摆,若还矩阵和还没到达k,就继续从第三行第一列向下摆……以此类推
若按照这样摆,我们会发现,当k是n的倍数时(即k%n=0时),每行每列的1的个数都相同(如果不信可以自己画画 -v- ),而其他情况下,行和差与列和差也只是为1,因此
f
(
A
)
f(A)
f(A)为2
输入
输入由多个测试用例组成。
第一行包含一个整数t(1≤t≤100)。接下来的t行包含测试用例的描述。
对于每个测试用例,只有一行包含两个整数n,k(1≤n≤300,0≤k≤n2)。
保证所有测试用例的n2之和不超过105。
输出
对于每个测试用例,首先打印满足条件的所有表中
f
(
A
)
f(A)
f(A)的最小可能值。
之后,打印n行包含n个字符。第i行中的第j个字符应等于
A
i
,
j
A_{i,j}
Ai,j。
如果有多个答案,您可以打印任何答案。
my Accepted code
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#define ll long long
#define db double
#define inf INT_MAX
#define s(a, n) memset(a, n, sizeof(a))
#define rep(l, a, b) for (ll l = a; l < b; ++l)
#define per(l, a, b) for (ll l = a; l >= b; --l)
#define debug(a) cout << '#' << a << '#' << endl
using namespace std
;
bool fi
= true;
const unsigned long long MOD
= 1e9 + 7;
int maps
[305][305];
int main() {
ios
::sync_with_stdio(false);
cin
.tie(0), cout
.tie(0);
int t
, n
, k
;
cin
>> t
;
while (t
--) {
if (fi
)
fi
= !fi
;
else
cout
<< endl
;
s(maps
, 0);
cin
>> n
>> k
;
int l
= k
% n
;
if (l
== 0)
cout
<< 0 << endl
;
else
cout
<< 2 << endl
;
int s1
= 0, s2
= 0, c
= 0, x1
= 0, x2
= n
- 1;
while (1) {
for (int i
= s1
, j
= s2
; i
< n
&& j
< n
&& c
< k
; i
++, j
++, c
++) {
maps
[i
][j
] = 1;
}
s1
++;
if (c
>= k
) break;
for (int i
= x1
, j
= x2
; i
< n
&& j
< n
&& c
< k
; i
++, j
++, c
++) {
maps
[i
][j
] = 1;
}
x2
--;
if (c
>= k
) break;
}
rep(i
, 0, n
) {
cout
<< maps
[i
][0];
rep(j
, 1, n
) { cout
<< maps
[i
][j
]; }
if (i
!= n
- 1) cout
<< endl
;
}
}
}
ps.D题第一次交的时候思路没错,就是多输出了空格,调试了半个小时发现原因。原本可以拿1000+分。。结果最后只有860。在哭啊.jpg