标签:dfs+剪枝。

题解:

  这道题看着就像一道dfs题目,没有什么算法可以用来算这个东西,于是想想暴搜。
  如果我们确定因为是2*2的子矩阵的和,如果确定了其中三个,那么就可以确定第四个,发现如果确定了第一行和第一列的话,就可以确定整个矩阵了,于是我们枚举只有399个了。
  因为要求字典序最小,我们先默认第一行和第一列全部是0,求出一个矩阵。我们先搜索第一行,从左到右。发现在(1,1)位置的数+k,那么在除了第一行和第一列的矩阵中,要合法,就要i+j为偶数的-=k,i+j为奇数的+=k即可。同样在(1,j)位置+=k,那么只影响这一列,便偶数行号-=k,奇数行号+=k即可。我们在保证了第一行最小的情况下,只要保证第一列最小即可满足字典序最小,因为确定第一行和第一列可以唯一的确定一个矩阵。
  第一行我们暴搜,当然需要剪枝了,对于每搜到第一行的一个数,就要扫一遍这一列,并且更新这一列的每个元素的所在行的行首的范围,也就是矩阵第一列每一个元素的范围,因为矩阵中的每一个元素只被三个数影响,那就是(1,1),以及行首与列首。更新了第一列每一个元素的范围之后,如果冲突即(L>R)那么就返回0。
  这里有一个技巧:按道理范围只要开一个O(n)的数组即可,但是这样需要备份,因为如过搜索失败了,那么回溯也要恢复范围数组的值,很麻烦,那么我们直接开一个二维数组,每次更新时取上一列的值与当前值比较之后再更新,这样就没有回溯的问题了,因为我们是从左到右枚举第一行的。

 #include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=,INF=0x3f3f3f3f;
int n,m,P;
int L[MAXN][MAXN],R[MAXN][MAXN],A[MAXN][MAXN];
inline int gi(){int res; scanf("%d",&res); return res;}
int F(int x){return (x&)?:-;}
int cal(int x,int y) { return A[x][y]+F(x+y)*A[][]+F(y)*L[x][m]+F(x)*A[][y]; }
bool dfs(int y)
{
if(y>m)return ;
int bacl[MAXN]={},bacr[MAXN]={};
for(A[][y]=;A[][y]<P;A[][y]++)
{
bool flag=;
for(int i=;i<=n;i++)
{
int tl=(A[i][y] + A[][]*F(i+y) + A[][y]*F(i)) * F(y+);
int tr=(A[i][y] + A[][]*F(i+y) + A[][y]*F(i)-(P-)) * F(y+);
if(tl>tr)swap(tl,tr);
L[i][y]=max(L[i][y-],tl);
R[i][y]=min(R[i][y-],tr);
if(L[i][y]>R[i][y])
{flag=; break;}
}
if(flag)
if(dfs(y+))
return ;
}
return ;
}
int main()
{
n=gi(); m=gi(); P=gi();
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
A[i][j]=gi();
if(i!= && j!=)
A[i][j]-=(A[i][j-]+A[i-][j]+A[i-][j-]);
R[i][j]=P-;
}
}
for(;A[][]<P;A[][]++)
{
if(dfs())
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
if(j== && i>)
printf("%d ",L[i][m]);
else if(i== && j>)
printf("%d%c",A[][j],j==m?'\n':' ');
else
printf("%d%c",cal(i,j),j==m?'\n':' ');
}
return ;
}
}
return ;
}

最新文章

  1. fzf by ruby
  2. MIME类型
  3. css important
  4. 关于maven-jetty-plugin 自动重启问题
  5. Ruby小例子
  6. C# Windows Phone App 开发,自制LockScreen 锁定画面类别(Class),从【网路图片】、【Assets资源】、【UI】修改锁定画面。
  7. Linux学习笔记-epoll
  8. 设计模式 -- 中介者设计模式 (Mediator Pattern)
  9. ACdream 1063 平衡树
  10. 算法模板——Dinic网络最大流 2
  11. SDRAM---页读写
  12. uni - 使用npm
  13. vba 列转行
  14. Spark2.x学习笔记:Spark SQL快速入门
  15. python之用户登陆作业
  16. oracle定时器job的使用
  17. 咏南中间件增加HTTPS.SYS支持
  18. -bash: xxx: /bin/sh^M: bad interpreter: No such file or directory
  19. CDOJ 1277 智商杯考试 每周一题 div2 二分+数学
  20. perl中一些模块的ubuntu中依赖包

热门文章

  1. 【BZOJ1014】[JSOI2008]火星人prefix Splay+hash
  2. HTML初级教程
  3. extjs grid renderer参数用法
  4. Gym - 100283K K. Cubes Shuffling —— 贪心
  5. node.js 开发博客系统
  6. FusionCharts Free 甘特图
  7. 「UOJ#117」 欧拉回路
  8. [HAOI 2012] 容易题
  9. 【原】Cache Buffer Chain 第四篇
  10. python学习笔记——Thread常用方法