大家吸取我的教训,想好再写。我码了好长时间,最后发现算法处理的是另一个问题,我处理的是正方形情况的,才能用我优化之后的记忆化搜索,然而矩形就凉了。

先看一下题吧:

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的更多相关文章

  1. [BZOJ1047][HAOI2007]理想的正方形(RMQ+DP)

    题意 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 思路 RMQ求 再DP 代码 #include<cstdio> #i ...

  2. 理想的正方形 HAOI2007(二维RMQ)

    理想的正方形 省队选拔赛河南  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master       题目描述 Description 有一个a*b的整数组成的矩阵,现 ...

  3. HAOI2007 理想的正方形

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1402  Solved: 738[Submit][Sta ...

  4. RAM——[HAOI2007]理想的正方形

    题目:[HAOI2007]理想的正方形 描述: [问题描述] 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. [输入]: 第一行为3个 ...

  5. [Luogu 2216] [HAOI2007]理想的正方形

    [Luogu 2216] [HAOI2007]理想的正方形 题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输 ...

  6. P2216 [HAOI2007]理想的正方形 (单调队列)

    题目链接:P2216 [HAOI2007]理想的正方形 题目描述 有一个 \(a\times b\)的整数组成的矩阵,现请你从中找出一个 \(n\times n\)的正方形区域,使得该区域所有数中的最 ...

  7. BZOJ1047: [HAOI2007]理想的正方形 [单调队列]

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2857  Solved: 1560[Submit][St ...

  8. 【bzoj1047】理想的正方形

    [bzoj1047]理想的正方形 题意 给定\(a*b\)由整数组成的矩形. 现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值 的差最小. \(1\leq a,b\leq 10 ...

  9. bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp

    题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2369  Solved: 1266[Submi ...

随机推荐

  1. Angular——内置指令

    内置指令 ng-app 指定应用根元素,至少有一个元素指定了此属性. ng-controller 指定控制器 ng-show控制元素是否显示,true显示.false不显示 ng-hide控制元素是否 ...

  2. html5——伸缩比例案例(携程)

    1.有图片的盒子,最好是父盒子设置伸缩属性,a标签设置伸缩比例1,img标签宽度100% 2.不要见到父盒子就设置伸缩属性,而是根据子盒子是否占据一行,若是子盒子占据一行,那么只要给子盒子设置伸缩比例 ...

  3. CSS——img

    img标签初始化:在低版本的ie浏览器会自带边框,所以建议border:0px.

  4. c指针之内存释放

    // 1.正常使用包含指针的结构体 // 2.正常使用元素类型为指针的vector #include<string.h> #include<stdio.h> #include& ...

  5. RTL Compiler之Technology Library

    1 Target Library Design Compiler uses the target library to build a circuit. During mapping, Design ...

  6. Java 基础入门随笔(2) JavaSE版——关键字、进制转换、类型转换

    1.Java语言-关键字 关键字:被java语言赋予了特殊含义的词,特点是所有的字母都为小写. java涉及到的关键字整理: 用于定义数据类型的关键字 class interface byte sho ...

  7. Web 服务器与应用服务器的区别是什么?

    不太严谨的说法:web服务器就是负责接收用户的Request,然后响应html等给客户浏览器.应用服务器处理一些业务逻辑等. 作者:luo链接:https://www.zhihu.com/questi ...

  8. C# 获得枚举值中所有数据到Array(数组)中

    Array LogType = Enum.GetValues(LogTypes.登录.GetType()); public enum LogTypes { 登录, 添加, 修改, 删除, 导出, 异常 ...

  9. RocketMQ学习笔记(4)----RocketMQ搭建双Master集群

    前面已经学习了RockeMQ的四种集群方式,接下来就来搭建一个双Master(2m)的集群环境. 1. 双Master服务器环境 序号 ip 用户名 密码 角色 模式 (1) 47.105.145.1 ...

  10. JpGraph 画图

    1:借鉴地址 PHP jpgraph安装及基本用法 http://www.php.cn/php-weizijiaocheng-400977.html JpGraph使用详解之中文乱码解决方法 http ...