【BZOJ2003】[HNOI2010]矩阵(搜索)
【BZOJ2003】[HNOI2010]矩阵(搜索)
题面
懒得粘了,不难找吧。
题解
看的学长写的题解,也懒得写了
大概是这样的。
不难发现只需要确定第一行和第一列就能确定答案,而确定第一行之后每确定一行的第一个数,这一行就全部确定了。所以只需要保证第一行和第一列的字典序最小就好了。
首先我们随意构造一组解,不难发现如果我们要给(1,1)位置上的数\(+1\)的话,那么黑白染色之后一部分位置\(+1\),一部分位置\(-1\)才能重新满足平衡。
所以我们先枚举(1,1),又不难发现一个位置在\((1,1)\)确定之后,它可以填的数字之和这一行的第一个和这一列的第一个数字相关了,那么我们枚举第一行的数字,能够通过值域限制反解出这一行的第一个数字的限制来判断是否合法。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 250
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,m,P,a[MAX][MAX],L[MAX][MAX],R[MAX][MAX];
int pw(int x){return (x&1)?1:-1;}
bool dfs(int y)
{
if(y>m)return true;
for(a[1][y]=0;a[1][y]<P;++a[1][y])
{
bool fl=true;
for(int i=2;i<=n;++i)
{
int l=a[i][y]+a[1][1]*pw(i+y)+a[1][y]*pw(i);
int r=l-(P-1);l*=pw(y+1);r*=pw(y+1);
if(l>r)swap(l,r);
L[i][y]=max(L[i][y-1],l);R[i][y]=min(R[i][y-1],r);
if(L[i][y]>R[i][y]){fl=false;break;}
}
if(fl&&dfs(y+1))return true;
}
return false;
}
int calc(int i,int j){return a[i][j]+pw(i+j)*a[1][1]+pw(j)*L[i][m]+pw(i)*a[1][j];}
void output()
{
for(int i=1;i<=n;++i,puts(""))
for(int j=1;j<=m;++j)
if(j==1&&i>1)printf("%d ",L[i][m]);
else if(i==1&&j>1)printf("%d ",a[1][j]);
else printf("%d ",calc(i,j));
puts("");
}
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();
if(i!=1&&j!=1)a[i][j]-=a[i][j-1]+a[i-1][j]+a[i-1][j-1];
R[i][j]=P-1;
}
for(a[1][1]=0;a[1][1]<P;++a[1][1])
if(dfs(2)){output();return 0;}
return 0;
}
【BZOJ2003】[HNOI2010]矩阵(搜索)的更多相关文章
- bzoj2003 [Hnoi2010]矩阵
Description Input 第一行包含三个正整数N M P表示矩阵的行数列数以及每个数的范围,接下来N行每行包含M个非负整数,其中第i行第j个数表示以格子(i,j)为右下角的2*2子矩阵中的数 ...
- [HNOI2010] 矩阵 matrix
标签:dfs+剪枝. 题解: 这道题看着就像一道dfs题目,没有什么算法可以用来算这个东西,于是想想暴搜. 如果我们确定因为是2*2的子矩阵的和,如果确定了其中三个,那么就可以确定第四个,发现如果确定 ...
- leetcode74:二维矩阵搜索问题
使用递归的方式解决,对于matrix,在左上角x,y,右下角xx,yy组成的区域内搜索target. mx=x和xx的中点,my=y和yy的中点 判断matrix[mx][my],如果它大于targe ...
- R dataframe 遗忘, which 矩阵搜索
A data frame is used for storing data tables. It is a list of vectors of equal length. For example, ...
- 剑指Offer(十九):顺时针打印矩阵
剑指Offer(十九):顺时针打印矩阵 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baid ...
- 【剑指 Offer】12.矩阵中的路径
题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格. 如果一条路径经过了矩阵的某一格,那么 ...
- CSDN总结的面试中的十大算法
1.String/Array/Matrix 在Java中,String是一个包含char数组和其它字段.方法的类.如果没有IDE自动完成代码,下面这个方法大家应该记住: toCharArray() / ...
- [算法专题] 二分搜索&排序数组
基础知识 二分非递归写法: int binary_search(const int a[], const int size, const int val) { int lower = 0; int u ...
- NOIP2002-2017普及组题解
虽然普及组一般都是暴力省一,但是有一些题目还是挺难的qwq个人觉得能进TG的题目会在前面打上'*' NOIP2002(clear) #include<bits/stdc++.h> usin ...
随机推荐
- Java 面试题 队列
Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构 Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Deque接 口. Q ...
- 汇编 LOOP,LOOPD指令
一.LOOP指令 循环控制指令LOOP 格式: LOOP 标号 loopd 功能: 1.ECX=ECX-1 2.(ECX)<>0,则转移至标号处循环执行 3.直至(ECX)=0,继续执行后 ...
- python语言程序设计5
1, 评估函数eval() 去掉参数最外侧引号并执行余下语句的函数. 比如eval("1"),经过运行可以得到数字 1 去得是单双引号,不是括号哦.. 广泛来说,能将任何字符串的形 ...
- [朴智妍][Lullaby]
歌词来源:http://music.163.com/#/song?id=484056971 作曲 : Bum/Sophiya/김용신 [作曲 : Bum/Sophiya/k/gi-myong-xin] ...
- linux下向一个文件中的某行插入数据的做法
sed -i 'ni\x' test.file 表示向test.file文件里的第n行的前面添加x内容sed -i 'na\x' test.file 表示向test.file ...
- 最小生成树模板题POJ - 1287-prim+kruskal
POJ - 1287超级模板题 大概意思就是点的编号从1到N,会给你m条边,可能两个点之间有多条边这种情况,求最小生成树总长度? 这题就不解释了,总结就算,prim是类似dijkstra,从第一个点出 ...
- C. The Tower is Going Home
链接 [http://codeforces.com/contest/1075/problem/C] 题意 有个1e9*1e9的棋盘(1,1)位置在左下角也就是车这枚棋子的位置,然后有n个在某一列后面划 ...
- 5 questions
1.软件开发中有哪几种过程模型? 2.详细设计有哪几种描述方法? 3.什么是需求分析? 4.软件设计的基本原理包括哪些内容? 5.简述文档在软件工程中的作用? 逸翔.
- 第六周分析Linux内核创建一个新进程的过程
潘恒 原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 task_struct结构: ...
- Linux内核分析——可执行程序的装载
链接的过程 首先运行C预处理器cpp,将C的源程序(a.c)翻译成ASCII码的中间文件(a.i) 接着C编译器ccl,将a.i翻译成ASCII汇编语言文件a.s 接着运行汇编器as,将a.s翻译成可 ...