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 ...
随机推荐
- CSS——◇demo
核心思想:嵌套盒子中的◇超过父盒子的部分隐藏. 第一种写法: <!DOCTYPE html> <html> <head> <meta charset=&quo ...
- CSS——background综合运用
搜索栏图标: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> < ...
- python 字典 get方法
在做项目的过程中,遇到了一个问题,数据保存到字典中,后来发现数据不对,排查了字典的构建过程,是OK的,后来怀疑是别的部分共用了这一个字典,排查代码,发现这里应该是有问题的. score = None ...
- JS监听事件错误:Uncaught TypeError: xx(函数名)is not a function at HTMLInputElement.onclick
事件监听一直出错,提示已定义的函数名不是一个函数,折腾了好久才想到,原来是函数名和JS内部关键字重名造成的. 以前也遇到过这种情况,但因为发生的概率比较小,就没太在意,但是这次感觉这方面确实需要注意, ...
- (转)Java任务调度框架Quartz入门教程指南(二) 使用job、trigger、schedule调用定时任务
http://blog.csdn.net/zixiao217/article/details/53044890 读完第一节,我们已经对Quartz有了一个大体的认识,它可以定时帮我们执行一些处理程序, ...
- iOS crash log 解析 symbol address = stack address - slide 运行时获取slide的api 利用dwarfdump从dsym文件中得到symbol
概述: 为什么 crash log 内 Exception Backtrace 部分的地址(stack address)不能从 dsym 文件中查出对应的代码? 因为 ASLR(Address spa ...
- Django的文件下载
在实际的项目中很多时候需要用到下载功能,如导excel.pdf或者文件下载,当然你可以使用web服务自己搭建可以用于下载的资源服务器,如nginx,这里我们主要介绍django中的文件下载. 我们这里 ...
- 报错:command not found
linux中如果是最小化安装的系统,执行命令的时候很多会出现没找到命令 [root@localhost ~]# mtr -bash: mtr: command not found [root@loca ...
- 《Mysql - 到底可不可以使用 Join ?》
一:Join 的问题? - 在实际生产中,使用 join 一般会集中在以下两类: - DBA 不让使用 Join ,使用 Join 会有什么问题呢? - 如果有两个大小不同的表做 join,应该用哪个 ...
- yum插件
参考文章: http://www.linuxfly.org/post/297/ [root@dnstest07.tbc /home/ahao.mah] #rpm -qa |grep yum yum-p ...