题目描述
现在给出一个 n × n n \times n n×n 阶行列式,求出它的值。
输入格式
第一行一个数
n
n
n表示行列式阶数
接下来是一个
n
n
n 行
n
×
n
n \times n
n×n 列的由整数构成的行列式
输出格式
(无)
样例输入
3
5 1 2
4 2 5
3 4 1
样例输出
-59
数据范围
1 ≤ n ≤ 10 1\leq n\leq 10 1≤n≤10
答案在int范围之内
行列式复习
众所周知,矩阵的行列式是这样的,我们不妨先假设一个
n
×
n
n \times n
n×n 阶行列式,如下图所示:
∣
A
∣
=
∣
a
1
,
1
a
1
,
2
a
1
,
3
…
a
1
,
n
a
2
,
1
a
2
,
2
a
2
,
3
…
a
2
,
n
a
3
,
1
a
3
,
2
a
3
,
3
…
a
3
,
n
⋮
⋮
⋮
⋱
⋮
a
n
,
1
a
n
,
2
a
n
,
3
…
a
n
,
n
∣
|A|=\begin{vmatrix} a_{1,1} & a_{1,2} & a_{1,3} &\dots & a_{1,n} \\ a_{2,1} & a_{2,2} & a_{2,3} & \dots & a_{2,n} \\ a_{3,1} & a_{3,2} & a_{3,3} & \dots & a_{3,n} \\ \vdots & \vdots & \vdots & \ddots & \vdots & \\ a_{n,1} & a_{n,2} & a_{n,3} & \dots & a_{n,n} \\ \end{vmatrix} \quad
∣A∣=∣∣∣∣∣∣∣∣∣∣∣a1,1a2,1a3,1⋮an,1a1,2a2,2a3,2⋮an,2a1,3a2,3a3,3⋮an,3………⋱…a1,na2,na3,n⋮an,n∣∣∣∣∣∣∣∣∣∣∣
要求出这个奇奇怪怪的东东,根据我们线性代数所学,有下面几种奇奇怪怪的方法hhh。(应该还有很多,只是这3个我比较熟练)
- 代数余子式的方法
- 逆序和的方法
- 采用行变换的方法,求对角线上的乘积
代数余子式方法
首先我们看看如果要用c佳佳实现这个玩野,那我们要用到什么知识。如果要用代数余子式的方法,那也就是说,要求出下面等式的和:(按照行展开)
∣
A
∣
=
∑
j
=
1
n
a
i
j
A
i
j
(
i
=
1
,
2
,
3
,
⋯
,
n
)
|A|=\sum\limits_{j=1}^{n}a_{ij}A_{ij} (i=1,2,3, \cdots, n)
∣A∣=j=1∑naijAij(i=1,2,3,⋯,n)
或者按照列展开也可以:像这样
∣
A
∣
=
∑
i
=
1
n
a
i
j
A
i
j
(
j
=
1
,
2
,
3
,
⋯
,
n
)
|A|=\sum\limits_{i=1}^{n}a_{ij}A_{ij} (j=1,2,3, \cdots, n)
∣A∣=i=1∑naijAij(j=1,2,3,⋯,n)
补充一句,上面的式子中:
A
i
j
A_{ij}
Aij表示元素
a
i
j
a_{ij}
aij 的代数余子式,而在引入代数余子式之前我们首先要知道余子式的概念,
M
i
j
M_{ij}
Mij 表示划掉第
i
i
i 行,划掉第
j
j
j 列的行列式,而两者之间的关系是:
A
i
j
=
(
−
1
)
i
+
j
M
i
j
A_{ij} = (-1)^{i+j} \ M_{ij}
Aij=(−1)i+j Mij
为了展示清楚我们还是假设有一个
n
×
n
n \times n
n×n 阶的矩阵
A
=
(
a
1
,
1
a
1
,
2
a
1
,
3
…
a
1
,
j
−
1
a
1
,
j
a
1
,
j
+
1
…
a
1
,
n
a
2
,
1
a
2
,
2
a
2
,
3
…
a
2
,
j
−
1
a
2
,
j
a
2
,
j
+
1
…
a
2
,
n
a
3
,
1
a
3
,
2
a
3
,
3
…
a
3
,
j
−
1
a
3
,
j
a
3
,
j
+
1
…
a
3
,
n
a
4
,
1
a
4
,
2
a
4
,
3
…
…
…
…
…
…
⋮
⋮
⋮
⋱
⋮
⋮
⋮
⋮
⋮
a
i
−
1
,
1
a
i
−
1
,
2
a
i
−
1
,
3
…
a
i
−
1
,
j
−
1
a
i
−
1
,
j
a
i
−
1
,
j
+
1
…
a
i
−
1
,
n
a
i
,
1
a
i
,
2
a
i
,
3
…
a
i
,
j
−
1
a
i
,
j
a
i
,
j
+
1
…
a
i
,
n
a
i
+
1
,
1
a
i
+
1
,
2
a
i
+
1
,
3
…
a
i
+
1
,
j
−
1
a
i
+
1
,
j
a
i
+
1
,
j
+
1
…
a
i
+
1
,
n
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
a
n
,
1
a
n
,
2
a
n
,
3
…
a
n
,
j
−
1
a
n
,
j
a
n
,
j
+
1
…
a
n
,
n
)
A=\left (\begin{array}{ccccc|c|c} a_{1,1} & a_{1,2} & a_{1,3} &\dots & a_{1,j-1} & a_{1,j} & a_{1,j+1} &\dots & a_{1,n}\\ a_{2,1} & a_{2,2} & a_{2,3} & \dots & a_{2,j-1} & a_{2,j} & a_{2,j+1} &\dots & a_{2,n} \\ a_{3,1} & a_{3,2} & a_{3,3} & \dots & a_{3,j-1} & a_{3,j} & a_{3,j+1}&\dots & a_{3,n} \\ a_{4,1} & a_{4,2} & a_{4,3} & \dots & \dots & \dots &\dots & \dots & \dots \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots &\vdots & \vdots & \vdots \\ a_{i-1,1} & a_{i-1,2} & a_{i-1,3} & \dots & a_{i-1,j-1} & a_{i-1,j} & a_{i-1,j+1} & \dots & a_{i-1,n} \\ \hline a_{i,1} & a_{i,2} & a_{i,3} & \dots & a_{i,j-1} & a_{i,j}& a_{i,j+1} & \dots & a_{i,n} \\ \hline a_{i+1,1} & a_{i+1,2} & a_{i+1,3} & \dots & a_{i+1,j-1} & a_{i+1,j} & a_{i+1,j+1} & \dots & a_{i+1,n} \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots &\vdots & \vdots & \vdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots &\vdots & \vdots & \vdots \\ a_{n,1} & a_{n,2} & a_{n,3} &\dots & a_{n,j-1} & a_{n,j} & a_{n,j+1} &\dots & a_{n,n}\\ \end{array}\right)
A=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛a1,1a2,1a3,1a4,1⋮ai−1,1ai,1ai+1,1⋮⋮an,1a1,2a2,2a3,2a4,2⋮ai−1,2ai,2ai+1,2⋮⋮an,2a1,3a2,3a3,3a4,3⋮ai−1,3ai,3ai+1,3⋮⋮an,3…………⋱………⋮⋮…a1,j−1a2,j−1a3,j−1…⋮ai−1,j−1ai,j−1ai+1,j−1⋮⋮an,j−1a1,ja2,ja3,j…⋮ai−1,jai,jai+1,j⋮⋮an,ja1,j+1a2,j+1a3,j+1…⋮ai−1,j+1ai,j+1ai+1,j+1⋮⋮an,j+1…………⋮………⋮⋮…a1,na2,na3,n…⋮ai−1,nai,nai+1,n⋮⋮an,n⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞
去掉第
i
i
i 行,去掉第
j
j
j 列,结果如下图所示
∣
M
i
j
∣
=
∣
a
1
,
1
a
1
,
2
a
1
,
3
⋯
a
1
,
j
−
1
a
1
,
j
+
1
…
a
1
,
n
a
2
,
1
a
2
,
2
a
2
,
3
⋯
a
2
,
j
−
1
a
2
,
j
+
1
…
a
2
,
n
a
3
,
1
a
3
,
2
a
3
,
3
⋯
a
3
,
j
−
1
a
3
,
j
+
1
…
a
3
,
n
⋮
⋮
⋮
⋱
⋮
⋮
⋮
⋮
a
i
−
1
,
1
a
i
−
1
,
2
a
i
−
1
,
3
…
a
i
−
1
,
j
−
1
a
i
−
1
,
j
+
1
…
a
i
−
1
,
n
a
i
+
1
,
1
a
i
+
1
,
2
a
i
+
1
,
3
…
a
i
+
1
,
j
−
1
a
i
+
1
,
j
+
1
…
a
i
+
1
,
n
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
a
n
,
1
a
n
,
2
a
n
,
3
…
a
n
,
j
−
1
a
n
,
j
+
1
…
a
n
,
n
∣
|M_{ij}|=\begin{vmatrix} a_{1,1} & a_{1,2} & a_{1,3} &\cdots & a_{1,j-1} & a_{1,j+1} &\dots & a_{1,n}\\ a_{2,1} & a_{2,2} & a_{2,3} & \cdots & a_{2,j-1} & a_{2,j+1} &\dots & a_{2,n} \\ a_{3,1} & a_{3,2} & a_{3,3} & \cdots & a_{3,j-1} & a_{3,j+1}&\dots & a_{3,n} \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots &\vdots & \vdots \\ a_{i-1,1} & a_{i-1,2} & a_{i-1,3} & \dots & a_{i-1,j-1} & a_{i-1,j+1} & \dots & a_{i-1,n} \\ a_{i+1,1} & a_{i+1,2} & a_{i+1,3} & \dots & a_{i+1,j-1} & a_{i+1,j+1} & \dots & a_{i+1,n} \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots &\vdots & \vdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots &\vdots & \vdots \\ a_{n,1} & a_{n,2} & a_{n,3} &\dots & a_{n,j-1} & a_{n,j+1} &\dots & a_{n,n}\\ \end{vmatrix} \quad
∣Mij∣=∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣a1,1a2,1a3,1⋮ai−1,1ai+1,1⋮⋮an,1a1,2a2,2a3,2⋮ai−1,2ai+1,2⋮⋮an,2a1,3a2,3a3,3⋮ai−1,3ai+1,3⋮⋮an,3⋯⋯⋯⋱……⋮⋮…a1,j−1a2,j−1a3,j−1⋮ai−1,j−1ai+1,j−1⋮⋮an,j−1a1,j+1a2,j+1a3,j+1⋮ai−1,j+1ai+1,j+1⋮⋮an,j+1………⋮……⋮⋮…a1,na2,na3,n⋮ai−1,nai+1,n⋮⋮an,n∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣
带入即可得到:
A
i
j
=
(
−
1
)
i
+
j
∣
a
1
,
1
a
1
,
2
a
1
,
3
⋯
a
1
,
j
−
1
a
1
,
j
+
1
…
a
1
,
n
a
2
,
1
a
2
,
2
a
2
,
3
⋯
a
2
,
j
−
1
a
2
,
j
+
1
…
a
2
,
n
a
3
,
1
a
3
,
2
a
3
,
3
⋯
a
3
,
j
−
1
a
3
,
j
+
1
…
a
3
,
n
⋮
⋮
⋮
⋱
⋮
⋮
⋮
⋮
a
i
−
1
,
1
a
i
−
1
,
2
a
i
−
1
,
3
…
a
i
−
1
,
j
−
1
a
i
−
1
,
j
+
1
…
a
i
−
1
,
n
a
i
+
1
,
1
a
i
+
1
,
2
a
i
+
1
,
3
…
a
i
+
1
,
j
−
1
a
i
+
1
,
j
+
1
…
a
i
+
1
,
n
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
⋮
a
n
,
1
a
n
,
2
a
n
,
3
…
a
n
,
j
−
1
a
n
,
j
+
1
…
a
n
,
n
∣
A_{ij} = (-1)^{i+j}\begin{vmatrix} a_{1,1} & a_{1,2} & a_{1,3} &\cdots & a_{1,j-1} & a_{1,j+1} &\dots & a_{1,n}\\ a_{2,1} & a_{2,2} & a_{2,3} & \cdots & a_{2,j-1} & a_{2,j+1} &\dots & a_{2,n} \\ a_{3,1} & a_{3,2} & a_{3,3} & \cdots & a_{3,j-1} & a_{3,j+1}&\dots & a_{3,n} \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots &\vdots & \vdots \\ a_{i-1,1} & a_{i-1,2} & a_{i-1,3} & \dots & a_{i-1,j-1} & a_{i-1,j+1} & \dots & a_{i-1,n} \\ a_{i+1,1} & a_{i+1,2} & a_{i+1,3} & \dots & a_{i+1,j-1} & a_{i+1,j+1} & \dots & a_{i+1,n} \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots &\vdots & \vdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots &\vdots & \vdots \\ a_{n,1} & a_{n,2} & a_{n,3} &\dots & a_{n,j-1} & a_{n,j+1} &\dots & a_{n,n}\\ \end{vmatrix} \quad
Aij=(−1)i+j∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣a1,1a2,1a3,1⋮ai−1,1ai+1,1⋮⋮an,1a1,2a2,2a3,2⋮ai−1,2ai+1,2⋮⋮an,2a1,3a2,3a3,3⋮ai−1,3ai+1,3⋮⋮an,3⋯⋯⋯⋱……⋮⋮…a1,j−1a2,j−1a3,j−1⋮ai−1,j−1ai+1,j−1⋮⋮an,j−1a1,j+1a2,j+1a3,j+1⋮ai−1,j+1ai+1,j+1⋮⋮an,j+1………⋮……⋮⋮…a1,na2,na3,n⋮ai−1,nai+1,n⋮⋮an,n∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣∣
所以,就这么递归下去,阶数逐渐递减,一直到 1 1 1 阶即可得到答案。
求逆序和的方法
【逆序定义】一个排列中(如
1
,
5
,
3
,
4
,
2
1,5,3,4,2
1,5,3,4,2),如果一个大的数排在一个小的数前面 【如
5
,
2
5,2
5,2】,就称这两个数构成一个逆序。
【逆序和定义】一个排列中(如
1
,
5
,
3
,
4
,
2
1,5,3,4,2
1,5,3,4,2),所有逆序的数量叫做逆序和,如
1
,
5
,
3
,
4
,
2
1,5,3,4,2
1,5,3,4,2有5个逆序。我们记作
r
(
1
,
5
,
3
,
4
,
2
)
=
5
r(1,5,3,4,2)=5
r(1,5,3,4,2)=5,以此类推,一个排列
b
1
,
b
2
,
⋯
b
n
b_1,b_2,\cdots b_n
b1,b2,⋯bn 的逆序和记作:
r
(
b
1
b
2
b
3
⋯
a
n
)
r(b_1b_2b_3\cdots a_n)
r(b1b2b3⋯an)
基于此,行列式计算可以用下面的公式
∣
A
∣
=
∑
b
1
b
2
b
3
⋯
b
n
a
1
,
b
1
a
2
,
b
2
a
3
,
b
3
⋯
a
n
,
b
n
|A|=\sum\limits_{b_1b_2b_3\cdots b_n}a_{1,b_1}a_{2,b_2}a_{3,b_3}\cdots a_{n,b_n}
∣A∣=b1b2b3⋯bn∑a1,b1a2,b2a3,b3⋯an,bn
即为:
∣
A
∣
=
∑
b
1
b
2
b
3
⋯
b
n
(
(
−
1
)
r
(
b
1
b
2
b
3
⋯
a
n
)
∏
i
=
1
n
a
i
,
a
i
)
|A|=\sum\limits_{b_1b_2b_3\cdots b_n}((-1)^{r(b_1b_2b_3\cdots a_n)}\prod\limits_{i=1}^na_{i,a_i})
∣A∣=b1b2b3⋯bn∑((−1)r(b1b2b3⋯an)i=1∏nai,ai)
注:
b
1
,
b
2
,
⋯
b
n
b_1,b_2,\cdots b_n
b1,b2,⋯bn 为
0
∼
n
−
1
0\sim n-1
0∼n−1的全排列。
题目解答
说完了行列式,我们还是思考如何解题目,我们有三种思路,显然按照第三种,我们会产生一些分式,例如,为了归一化,我们第一行首先就要除以 a 1 , 1 a_1,1 a1,1,再乘以 a 2 , 1 a_{2,1} a2,1,然后加到第二行,显然会由于 double 带来最终结果的误差,这种方法还是先排除。
此外,如果我们采用余子式的方法,我们需要把余子式的行列式作为一个参数传入递归函数,有点困难(说白了就是我还不会略略略)
所以还是选择了逆序和的方法。
- 生成 n n n 个数字的全排列
- ∏ i = 1 n a i , a i \prod\limits_{i=1}^na_{i,a_i} i=1∏nai,ai要算出来
- 把前面算出来的加起来,得出结果
一切的一切开始前,我们看看要那些变量,先看全局变量(似乎都可以是全局变量)
int a[10000]; // 存放那个序列
int n; // 矩阵的阶数
int lixu = 0; // 逆序的个数(拼音不好请勿介意!)
double ** p; // 动态二维数组
int ans = 0; // 结果
首先,要生成全排首先要有一个序列,我们用数组来代替
cin >> n;
for (int i = 0; i < n; i++)
{
a[i] = i;
} //生成数组 : 0,1,2,3,4,5,6,7,8......
然后给我去看课本135面,课本是以 k k k 个字母的全排列(这个应该会吧,直接套就完事了)不会的看书去doge。
虽然但是还是说一下,举个例子,我们要输出字母ABCDE的全排列,有下面几种可能。
注:括号后面的方法都是基于ABCDE这个序列进行变换
- 字母A跟着后面的“BCDE”的全排列(方法:A与A自己交换,后面的递归,输出全排)
- 字母B跟着后面的“ACDE”的全排列(方法:A与B交换,后面的递归,输出全排)
- 字母C跟着后面的“ABDE”的全排列(方法:A与C交换,后面的递归,输出全排)
- 字母D跟着后面的“ABCE”的全排列(方法:A与D交换,后面的递归,输出全排)
- 字母E跟着后面的“ABCD”的全排列(方法:A与E交换,后面的递归,输出全排)
**递归函数的核心是终止的条件!!!**不管是什么递归,一定要写终止条件!,然后再递归
// 这个函数用来生成全排列,k表示已经排列好的元素个数,使用方法为Allsequenc_Generator(0);
// 递归终止的条件是 k = n; 这说明一组排列已经生成啦
void Allsequenc_Generator(int k)
{
if (k == n)
{
DataPocess(); // 课本上是到这里递归停止,输出结果,我这里相当于全排生成完毕,要开始计算
// 考虑到是全局变量,没有必要传递什么指针啥的,短平快
}
else
for (int i = k; i < n; i++)
{
swap(i, k);
Allsequenc_Generator(k + 1);
swap(i, k); // 这一段全是抄课本的,原理就是交换
}
}
然后是main函数的剩下部分,包括数据读取,动态数组的回收空间。
p = new double *[n]; // 空间的申请 p是二级指针,所以指向一级指针的数组首位!
for (int i = 0; i < n; i++)
{
p[i] = new double[n]; // 空间的申请 p[i]是一级指针,所以指向0级(可能是这样?)数组
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> p[i][j]; // 读取数据不多说
}
}
Allsequenc_Generator(0); // 产生全排,每产生一个全排就把数据处理掉
cout << ans; // 输出结果
for (int i = 0; i < n; i++)
delete[] p[i]; // 回收空间,先通过一级指针p[i]回收他指向的数组
delete[] p; // 回收空间,通过二级指针p回收他指向的一级指针数组
// system("pause");
return 0;
问题:逆序数怎么求?最呆的方法(还是可以过评测机)
lixu = 0;
for (int x = 0; x < n - 1; x++)
{
for (int y = x + 1; y < n; y++)
if (a[x] > a[y])
lixu++;
}
改进的方法,来自线代老师爱猫狂人!这么解释,对于一个单调递增的序列 如1,2,3,4,5,任意交换里面的两个元素,逆序数奇偶性一定变 。
那太好了,只要我们在swap函数里面动一下手脚!
void swap(int i, int k)
{
if (i != k)
lixu++; // 排除自己和自己交换,只要是i k不同,交换后逆序加一!奇偶性调整完成!
int temp = a[i];
a[i] = a[k];
a[k] = temp;
}
所以有人可能会问,逆序这个变量反应了什么?反映的是真正逆序的奇偶性,而不是真正逆序的和,毕竟最终只是一个负一的次方呢2333。
void DataPocess()
{
int temptimes = 1;
for (int j = 0; j < n; j++)
{
temptimes = temptimes * p[j][a[j]];
} // 全部乘起来!
if (lixu % 2 == 0) // 判断奇偶 偶数就加,反之就减
{
ans = ans + temptimes;
}
if (lixu % 2 == 1)
{
ans = ans - temptimes;
}
}
完整的AC代码:注释掉的是临时输出使用
#include <iostream>
using namespace std;
int a[10000];
int n;
int lixu = 0;
double ** p;
int ans = 0;
void DataPocess()
{
// lixu = 0;
// for (int x = 0; x < n - 1; x++)
// {
// for (int y = x + 1; y < n; y++)
// if (a[x] > a[y])
// lixu++;
// }
int temptimes = 1;
for (int j = 0; j < n; j++)
{
temptimes = temptimes * p[j][a[j]];
}
// cout << "temptimes" << temptimes << endl;
if (lixu % 2 == 0)
{
// cout << "temptimes: + " << temptimes << endl;
ans = ans + temptimes;
}
if (lixu % 2 == 1)
{
// cout << "temptimes: - " << temptimes << endl;
ans = ans - temptimes;
}
}
void swap(int i, int k)
{
if (i != k)
lixu++;
int temp = a[i];
a[i] = a[k];
a[k] = temp;
}
void Allsequenc_Generator(int k)
{
if (k == n)
{
DataPocess();
}
else
for (int i = k; i < n; i++)
{
swap(i, k);
Allsequenc_Generator(k + 1);
swap(i, k);
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
a[i] = i;
} //生成数组 : 0,1,2,3,4,5,6,7,8......
p = new double *[n];
for (int i = 0; i < n; i++)
{
p[i] = new double[n];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> p[i][j];
}
}
Allsequenc_Generator(0);
cout << ans;
for (int i = 0; i < n; i++)
delete[] p[i];
delete[] p;
// system("pause");
return 0;
}
还是附上评测记录,时间较长的是用的for循环求逆序,短的是改进后的结果。没想到吧优化明显!
评测编号 | 用户 | 题目名称 | 评测状态 | 运行时间 | 内存 | 语言 | 提交时间 |
---|---|---|---|---|---|---|---|
49055 | 1033. 行列式求值 | Accepted | 305ms | 32960KiB | C++ | Jul-20-2021 17:44:06 | |
49054 | 1033. 行列式求值 | Accepted | 1185ms | 32960KiB | C++ | Jul-20-2021 17:40:11 |