B1047 理想的正方形 RMQ
大家吸取我的教训,想好再写。我码了好长时间,最后发现算法处理的是另一个问题,我处理的是正方形情况的,才能用我优化之后的记忆化搜索,然而矩形就凉了。
先看一下题吧:
Description 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值
的差最小。
Input 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每
行相邻两数之间用一空格分隔。
%的数据2<=a,b<=,n<=a,n<=b,n<=
Output 仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值。
Sample Input Sample Output HINT Source
我的反面教材代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
int a,b,n;
int p[][];
int f[][][][];
int l[];
void dfs(int o,int x1,int y1,int x2,int y2)
{
if(f[x1][y1][o][] != -)
return;
if(x1 == x2 && y1 == y2)
{
f[x1][y1][o][] = p[x1][y1];
f[x1][y1][o][] = p[x1][y1];
return;
}
int minn = INF;
int maxn = ;
dfs(o + ,x1,y1,x1 + l[o],y1 + l[o]);
dfs(o + ,a - l[o],y1,a,y1 + l[o]);
dfs(o + ,x1,b - l[o],x1 + l[o],b);
dfs(o + ,a - l[o],b - l[o],a,b);
// printf("%d %d %d %d\n",a - l[o],b - l[o],a,b);
maxn = max(maxn,f[x1][y1][o + ][]);
minn = min(minn,f[x1][y1][o + ][]);
maxn = max(maxn,f[a - l[o]][y1][o + ][]);
minn = min(minn,f[a - l[o]][y1][o + ][]);
maxn = max(maxn,f[x1][b - l[o]][o + ][]);
minn = min(minn,f[x1][b - l[]][o + ][]);
maxn = max(maxn,f[a - l[o]][b - l[o]][o + ][]);
minn = min(minn,f[a - l[o]][b - l[o]][o + ][]);
f[x1][y1][o][] = maxn;
f[x1][y1][o][] = minn;
return;
}
int main()
{
memset(f,-,sizeof(f));
read(a);read(b);read(n);
duke(i,,a)
{
duke(j,,b)
read(p[i][j]);
}
int k = n,len = ;
while(k > )
{
k = ceil(k / );
l[++len] = k;
// cout<<k<<endl;
}
duke(i,,a - n)
duke(j,,b - n)
dfs(,i,j,i + n,j + n);
printf("%d %d\n",f[][][][],f[][][][]);
return ;
}
/*
5 4 2
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2
*/
然后就凉了,懒得写了,用二维的RMQ搞一下,抄了个比较清晰的代码。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; const int INF = ;
const int maxm = + ;
const int maxn = + ;
const int maxlog = ; int a, b, n;
int logn;
int grid[maxm][maxm];
int maxv[maxm][maxm], minv[maxm][maxm]; int query (int x, int y)
{
int _max = , _min = ;
_max = max(maxv[x][y], max(maxv[x+n-(<<logn)][y+n-(<<logn)], max(maxv[x+n-(<<logn)][y], maxv[x][y+n-(<<logn)])));
_min = min(minv[x][y], min(minv[x+n-(<<logn)][y+n-(<<logn)], min(minv[x+n-(<<logn)][y], minv[x][y+n-(<<logn)])));
return _max - _min;
} int main ()
{
// freopen("in.txt", "r", stdin);
cin >> a >> b >> n;
for (int i = ; i < a; i++)
for (int j = ; j < b; j++)
{
scanf("%d", &grid[i][j]);
maxv[i][j] = minv[i][j] = grid[i][j];
} for (logn = ; ((<<(logn+)) <= n); logn++);
for (int k = ; k < logn; k++)
for (int i = ; i+(<<k) < a; i++)
for (int j = ; j+(<<k) < b; j++)
{
maxv[i][j] = max(maxv[i][j], max(maxv[i+(<<k)][j+(<<k)], max(maxv[i+(<<k)][j], maxv[i][j+(<<k)])));
minv[i][j] = min(minv[i][j], min(minv[i+(<<k)][j+(<<k)], min(minv[i+(<<k)][j], minv[i][j+(<<k)])));
} int ans = INF;
for (int i = ; i <= a-n; i++)
for (int j = ; j <= b-n; j++)
ans = min(ans, query(i, j)); cout << ans;
return ;
}
唉,后悔啊。。。
B1047 理想的正方形 RMQ的更多相关文章
- [BZOJ1047][HAOI2007]理想的正方形(RMQ+DP)
题意 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 思路 RMQ求 再DP 代码 #include<cstdio> #i ...
- 理想的正方形 HAOI2007(二维RMQ)
理想的正方形 省队选拔赛河南 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description 有一个a*b的整数组成的矩阵,现 ...
- HAOI2007 理想的正方形
1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1402 Solved: 738[Submit][Sta ...
- RAM——[HAOI2007]理想的正方形
题目:[HAOI2007]理想的正方形 描述: [问题描述] 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. [输入]: 第一行为3个 ...
- [Luogu 2216] [HAOI2007]理想的正方形
[Luogu 2216] [HAOI2007]理想的正方形 题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输 ...
- P2216 [HAOI2007]理想的正方形 (单调队列)
题目链接:P2216 [HAOI2007]理想的正方形 题目描述 有一个 \(a\times b\)的整数组成的矩阵,现请你从中找出一个 \(n\times n\)的正方形区域,使得该区域所有数中的最 ...
- BZOJ1047: [HAOI2007]理想的正方形 [单调队列]
1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2857 Solved: 1560[Submit][St ...
- 【bzoj1047】理想的正方形
[bzoj1047]理想的正方形 题意 给定\(a*b\)由整数组成的矩形. 现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值 的差最小. \(1\leq a,b\leq 10 ...
- bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp
题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2369 Solved: 1266[Submi ...
随机推荐
- Hive扩展功能(一)--Parquet
软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...
- 3星|《IBM商业价值报告:区块链》:一些重要行业对区块链的态度和已经发生的区块链的应用
区块链项目开发指南 (区块链技术丛书) 介绍IBM的专家们调研许多重要行业与组织后总结的各行业对区块链的态度和实际的应用.看起来有点意思,不过有两个缺点: 1:这些实际已经发生的应用基本没看到相关的新 ...
- 2016.01.05 DOM笔记(一) 查找元素
DOM节点的种类 元素和标签是一个意思,例如<body>标签或者称为<body>元素 节点DOM的节点分为三类 元素节点,文本节点,属性节点 例如 <div id=‘b ...
- Git学习总结一(下载、初始化、添加文件)
Git下载地址 安装完成后,还需要最后一步设置,在命令行输入: $ git config --global user.name "Your Name" $ git config - ...
- java中一个数组不能放不同数据类型的值
在java中,数组不能放不同数据类型的值. 方法一: 多态 定义数组类型的时候定义为父类,而存进数组为父类的子类 public class test2 { public static void mai ...
- 面试:A
分析 System.Collections.Generic.List<T> 的 Remove<T> 方法和 Clear 方法的实现细节(不允许使用“移除”“清除”这种概念模糊的 ...
- hadoop datanode usages方差算法
stdDev 标准差(方差) 阐述及应用 简单来说,标准差是一组数值自平均值分散开来的程度的一种测量观念.一个较大的标准差,代表大部分的数值和其平均值之间差异较大:一个较小的标准差,代表这些数值较接近 ...
- TLE - Time Limit Exceeded
TLE - Time Limit Exceeded no tags Given integers N (1 ≤ N ≤ 50) and M (1 ≤ M ≤ 15), compute the num ...
- git 拉取远程分支 --本地分支不存在
git checkout -b 本地分支名 origin/远程分支名
- hdu 4280
题意:求XY平面上最左边的点到最右边的点的最大流. 分析:数据量大,EK算法TLE,要用SAP算法.SAP算法用的是 http://www.cnblogs.com/kuangbin/archive/2 ...