题意简述
给你一个 $n$ 行 $m$ 列的矩阵,要求你让这个矩阵是“完美”的。
“完美”的定义如下:
-
若当前的格子里是一个正整数 $k$,那么与这个网格相邻(有公共边)的 $k$ 个格子也必须有一个正整数。
-
若当前的格子里是 $0$,那么不受上述的限制。
你可以对任意的一个格子加上 $1$,次数不受限制。
题目分析
首先,我们可以发现一个在角上的格子只有 $2$ 个格子与其相邻,在边上的只有 $3$ 个格子相邻,而在中间部分的有 $4$ 个格子相邻。如果有格子超出上述限制,因为题目规定只能增加,不能减少,所以必定无解。
接下来,我们考虑如何构造合法的矩阵。
我们考虑将整个矩阵填满,即将角上填 $2$,边上填 $3$,中间部分填 $4$,可以看出这种情况一定是“完美”的。
最后,我们考虑操作的过程是否合法。因为上述判无解的过程已经保证了给出矩阵的数一定小于等于矩阵填满后的数,所以不会出现减少的情况,故合法。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=310;
int T,n,m,a[N][N];
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
{
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+ch-48;
ch=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
void solve()
{
n=read();
m=read();
bool flag=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]=read();
if((i==1||i==n)&&(j==1||j==m)&&a[i][j]>2) flag=1;
if((i==1||i==n)&&(j>1&&j<m)&&a[i][j]>3) flag=1;
if((j==1||j==m)&&(i>1&&i<n)&&a[i][j]>3) flag=1;
if(j>1&&j<m&&i>1&&i<n&&a[i][j]>4) flag=1;
}
}
if(flag)
{
printf("NO\n");
return;
}
printf("YES\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if((i==1||i==n)&&(j==1||j==m)) a[i][j]=2;
if((i==1||i==n)&&(j>1&&j<m)) a[i][j]=3;
if((j==1||j==m)&&(i>1&&i<n)) a[i][j]=3;
if(j>1&&j<m&&i>1&&i<n) a[i][j]=4;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
write(a[i][j]);
printf(" ");
}
printf("\n");
}
}
int main()
{
T=read();
while(T--)
{
solve();
}
return 0;
}
标签:ch,格子,int,题解,矩阵,flag,Grid,&&,CF1375B
From: https://www.cnblogs.com/zhuluoan/p/17978174