题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=2003

题解

考虑搜索。

确定了第一行和第一列,那么就确定了整个矩阵,因此搜索的范围可以降到399个位置。

首先搜索第一行,显然每个不是第一行第一列的位置都可以由三个位置唯一确定:(1,1),(1,i),(j,1)(1,1),(1,i),(j,1)。由于搜索的是第一行,可以把(i,j)(i,j)这个位置=0=0=p1=p-1都带入一遍,得到的结果就是(j,1)(j,1)的上下界。如果搜索的过程中发现冲突了那么说明第一行这样填不行,剪枝。

代码

#include <cstdio>
#include <algorithm>
 
int read()
{
  int x=0,f=1;
  char ch=getchar();
  while((ch<'0')||(ch>'9'))
    {
      if(ch=='-')
        {
          f=-f;
        }
      ch=getchar();
    }
  while((ch>='0')&&(ch<='9'))
    {
      x=x*10+ch-'0';
      ch=getchar();
    }
  return x*f;
}
 
const int maxn=200;
 
int n,m,p,a[maxn+10][maxn+10],l[maxn+10][maxn+10],r[maxn+10][maxn+10];
 
int f(int x)
{
  return (x&1)?1:-1;
}
 
int search(int y)
{
  if(y>m)
    {
      return 1;
    }
  for(a[1][y]=0; a[1][y]<p; ++a[1][y])
    {
      int flag=1;
      for(int i=2; i<=n; ++i)
        {
          int b=(0-a[1][1]*f(i+y)-a[1][y]*f(i)-a[i][y])*f(y),c=((p-1)-a[1][1]*f(i+y)-a[1][y]*f(i)-a[i][y])*f(y);
          if(b>c)
            {
              std::swap(b,c);
            }
          l[y][i]=std::max(l[y-1][i],b);
          r[y][i]=std::min(r[y-1][i],c);
          if(l[y][i]>r[y][i])
            {
              flag=0;
              break;
            }
        }
      if(flag)
        {
          if(search(y+1))
            {
              return 1;
            }
        }
    }
  return 0;
}
 
int main()
{
  n=read();
  m=read();
  p=read();
  for(int i=1; i<=n; ++i)
    {
      for(int j=1; j<=m; ++j)
        {
          a[i][j]=read();
        }
    }
  for(int i=2; i<=n; ++i)
    {
      for(int j=2; j<=m; ++j)
        {
          a[i][j]-=a[i-1][j]+a[i][j-1]+a[i-1][j-1];
        }
    }
  for(int i=2; i<=n; ++i)
    {
      l[1][i]=0;
      r[1][i]=p-1;
    }
  for(a[1][1]=0; a[1][1]<p; ++a[1][1])
    {
      if(search(2))
        {
          for(int i=1; i<=n; ++i)
            {
              for(int j=1; j<=m; ++j)
                {
                  if(i==1)
                    {
                      printf("%d%c",a[i][j],(j==m)?'\n':' ');
                    }
                  else if(j==1)
                    {
                      printf("%d%c",l[m][i],(j==m)?'\n':' ');
                    }
                  else
                    {
                      printf("%d%c",a[i][j]+a[1][1]*f(i+j)+a[1][j]*f(i)+l[m][i]*f(j),(j==m)?'\n':' ');
                    }
                }
            }
          return 0;
        }
    }
  return 0;
}