【LGR-188-Div.3】洛谷基础赛 #12 & Daily OI Round 4 B 题解
前置知识——奇偶性
我们都知道,偶数对 2 2 2 取模余数为 0 0 0, 奇数对 2 2 2 取模余数为 1 1 1。所以奇数或者偶数个偶数相加得到的一定还是偶数,因为余数之和还是为 0 0 0,所以可得: 奇数 * 偶数 = 偶数,偶数 * 偶数 = 偶数。再来看奇数个奇数相加的情况,此时余数之和为奇数个 1 1 1 相加,对 2 2 2 再取模最终余数显然为 1 1 1,也就是奇数 * 奇数 = 奇数。
思路
由于题面中显然需要求解的内容都和行和列的和有关,所以我们不妨算出 n ∗ n n * n n∗n 的网格内的标号总和 s u m sum sum 为 ∑ i = 1 n 2 i = ( 1 + n 2 ) ∗ n 2 / 2 \sum^{n^2}_{i = 1} i = (1 + n^2) * n^2 / 2 ∑i=1n2i=(1+n2)∗n2/2
显然,上式在
2
≤
n
2 \le n
2≤n 时为偶数。
我们特判一下当
n
=
1
n = 1
n=1 时,网格内有且仅有
1
1
1 一个数,满足题面对每行之和都是奇数的要求,但不满足每列之和都是偶数的要求,所以
n
=
1
n = 1
n=1 时,输出 “No”。
那么再来看一般的 2 ≤ n 2 \le n 2≤n 的情况,由于 s u m sum sum 为偶数,而 s u m sum sum 又等于列数 * 每列之和,所以由奇偶性可得:
- 列数和每列之和中必有一个是偶数。
- 行数和每行之和中必有一个是偶数。
第一条由题意可知,每列之和必为偶数,所以一定满足。
第二条由于每行之和题目要求必须都是奇数,所以行数必须是偶数,所以
n
n
n 为偶数。
综上,当 n n n 为奇数的时候,输出 “No”,否则输出 “Yes”。
代码实现
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n;//开 long long,因为 n 最高为 10^18.
cin >> n;
cout << ((n % 2 == 0) ? "Yes" : "No");//判断 n 的奇偶性并输出对应的结果。
return 0;
}
the first end.
date 2024.06.06
突然发现只写了赛时的一个比较伪的证明,补一下当 n n n 为偶数时一定有解的证明。
显然 n n n 为偶数可以分类为 n = 2 ( m o d 4 ) n = 2\ (mod\ 4) n=2 (mod 4), n = 0 ( m o d 4 ) n = 0\ (mod\ 4) n=0 (mod 4)(实在是不会打三个横线的等号o(╥﹏╥)o)
当 n = 2 ( m o d 4 ) n = 2\ (mod\ 4) n=2 (mod 4) 时, 显然,如果想要每行之和为奇,必须有奇数个奇数,那么不难想到,我们每行有一半数为奇,一半数为偶,就能成立 ( ( (这样奇数个数一定是 n = 1 ( m o d 4 ) n = 1\ (mod\ 4) n=1 (mod 4),显然这是个奇数 ) ) ),那么我们不难想到一种构造方法就是奇数列全填奇数,偶数列全填偶数这样就能构造出来了。
e.g.
再来讨论 n = 0 ( m o d 4 ) n = 0\ (mod\ 4) n=0 (mod 4) 的情况,这种情况显然不能和刚才那种情况用同样的处理方式,但是我们可以将它变成之前的形式,我们先讨论 3 − n 3-n 3−n 列,发现这显然可以按照 n = 2 ( m o d 4 ) n = 2\ (mod\ 4) n=2 (mod 4) 的情况处理,那么 1 − 2 1 - 2 1−2 列我们怎么处理呢?这时我们会发现我们需要让每行的前两个数相加为偶数不就行了?由奇偶性我们可以知道,只有偶数加偶数或奇数加奇数是偶数,那么我们不难想到我们可以把 1 − ( n / 2 ) 1 - (n/2) 1−(n/2) 行的前两个数都给填上奇数, ( n / 2 + 1 ) − n (n / 2 + 1) - n (n/2+1)−n 行的前两个数都填上偶数,这样就构造出来了,也就证明了 n n n 为偶数时都是可行的。
the second ending.