CF1734E 题解

题意简述

给出质数 $n(2\le n<350)$,并给出 $b_1,b_2,\cdots,b_n(0\le b_i<n)$,要求构造 $n\times n$ 的矩阵 $a$,使得:

  • $\forall i,j\in[1,n],a_{i,j}\in[0,n)$
  • $\forall i\in [1,n],a_{i,i}=b_i$
  • $\forall i,j,x,y\in[1,n](i\neq x,j\neq y),a_{i,j}+a_{x,y}\neq a_{i,y}+a_{x,j}$

题目分析

欢迎来到思维难度 $\gg$ 代码难度的构造题。

首先分析一下条件:

  • 第一个条件比较好实现,只要我们构造出的矩阵在模 $n$ 意义下仍满足第三个条件即可。

  • 第二个条件看似奇怪,似乎不容易构造出既满足第三个条件又满足第二个条件的矩阵,但是我们发现有这样一个性质:

    $(a_{i,j}+c)+a_{x,y}\neq (a_{i,y}+c)+a_{x,j}\Leftrightarrow a_{i,j}+a_{x,y}\neq a_{i,y}+a_{x,j}$($c$ 是任意常数)。

    这意味着如果我们构造出了任意一个满足第三个条件的矩阵,我们只需要对每行各指定一个常数 $c$,让该行所有元素都加上这个常数就可以满足第二个条件。

  • 第三个条件就是本题的重点了。我们对其进行一个转换得到:

    $$a_{i,j}+a_{x,y}\neq a_{i,y}+a_{x,j}\Leftrightarrow a_{i,j}-a_{i,y}\ne a_{x,j}-a_{x,y}$$

    也就是说,矩阵的每两行对应位置的两个元素之差皆不相等。这样我们不妨令第 $1$ 行的相邻元素之差都为 $1$,第 $2$ 行的相邻元素之差都为 $2$……第 $n-1$ 行的相邻元素之差都为 $n-1$,第 $n$ 行的相邻元素之差都为 $n$。一个例子就是 $a_{i,j}=ij$,即:

    $$a= \begin{bmatrix} 1& 2&3 &\cdots & n \\ 2& 4& 6&\cdots & 2n \\ 3& 6& 9&\cdots & 3n \\ \vdots & \vdots & \vdots&\ddots & \vdots \\ n& 2n& 3n&\cdots & n^2 \end{bmatrix} $$

    这个矩阵就满足第三个条件。

现在我们分析完了三个条件,只需要看一下刚刚构造的满足第三个条件的矩阵是否可以转变成满足前两个条件的形式即可。

首先这个矩阵是满足第一个条件的。这是因为 $ij+xy-iy-xj=(i-x)(j-y)$,而 $i\neq x,j\neq y$,且 $n$ 为质数,所以有 $\gcd(i-x,n)=\gcd(j-y,n)=1$,即 $(i-x)(j-y)\not\equiv0 \pmod n$。所以 $ij+xy\not\equiv iy+xj \pmod n$。因此将该矩阵所有元素对 $n$ 取模同样满足第三个条件。

为了满足第二个条件,我们让第 $i$ 行的所有元素加上 $b_i-i^2$ 即可,记得取模。

本题至此就解决了,代码十分简单(字面意思)。

代码实现

#include<bits/stdc++.h>
using namespace std;
int n,a[360];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;printf("\n"),i++)
        for(int j=1;j<=n;j++)
            printf("%d ",((i*j+a[i]-i*i)%n+n)%n);//原始值是 i*j,为了满足第二个条件加上a[i]-i*i,为了满足第一个条件对 n 取模
    return 0;
}
posted @ 2023-08-01 23:06  Hadtsti  阅读(1)  评论(0编辑  收藏  举报  来源