题目链接
题解
考虑搜索。
确定了第一行和第一列,那么就确定了整个矩阵,因此搜索的范围可以降到399个位置。
首先搜索第一行,显然每个不是第一行第一列的位置都可以由三个位置唯一确定:(1,1),(1,i),(j,1)(1,1),(1,i),(j,1)(1,1),(1,i),(j,1)。由于搜索的是第一行,可以把(i,j)(i,j)(i,j)这个位置=0=0=0和=p−1=p-1=p−1都带入一遍,得到的结果就是(j,1)(j,1)(j,1)的上下界。如果搜索的过程中发现冲突了那么说明第一行这样填不行,剪枝。
代码
#include#include 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] 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]