#二分,哈希 or dp#洛谷 4398 [JSOI2008]Blue Mary的战役地图
题目
求两个正方形矩阵的最大公共正方形矩阵边长
分析
第一种就是\(dp\):
设\(dp[x1][y1][x2][y2]\)表示第一个正方形矩阵以\((x1,y1)\)为右下角,
第二个正方形矩阵以\((x2,y2)\)为右下角所能得到的最大公共正方形矩阵边长
状态转移方程比较显然
第二种是二分:
二分答案,然后预处理和哈希,时间复杂度\(O(n^2log_2n)\)
代码(dp)
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=51;
int n,a[N][N],b[N][N],ans,dp[N][N][N][N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed max(int a,int b){return a>b?a:b;}
signed main(){
n=iut();
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j) a[i][j]=iut();
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j) b[i][j]=iut();
for (rr int ia=1;ia<=n;++ia)
for (rr int ja=1;ja<=n;++ja)
for (rr int ib=1;ib<=n;++ib)
for (rr int jb=1;jb<=n;++jb)
if (a[ia][ja]==b[ib][jb]){
rr int t=min(dp[ia][ja-1][ib][jb-1],dp[ia-1][ja][ib-1][jb]);
dp[ia][ja][ib][jb]=min(dp[ia-1][ja-1][ib-1][jb-1],t)+1;
ans=max(ans,dp[ia][ja][ib][jb]);
}
return !printf("%d",ans);
}
代码(二分)
#include <cstdio>
#include <cctype>
#include <unordered_map>
#define rr register
using namespace std;
typedef unsigned uit;
const uit N=51,bas0=4177,bas1=3977;
unordered_map<uit,bool>uk; int n,a[2][N][N];
uit p1[N],p2[N],h[2][N][N],s[N][N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void doit(int t,int m){
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j)
s[i][j]=s[i][j-1]*bas0+a[t][i][j];
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n-m+1;++j)
h[t][i][j]=s[i][j+m-1]-s[i][j-1]*p1[m];
for (rr int j=1;j<=n-m+1;++j)
for (rr int i=1;i<=n;++i)
s[i][j]=s[i-1][j]*bas1+h[t][i][j];
for (rr int j=1;j<=n-m+1;++j)
for (rr int i=1;i<=n-m+1;++i)
h[t][i][j]=s[i+m-1][j]-s[i-1][j]*p2[m];
}
inline bool check(int m){
doit(0,m),doit(1,m),uk.clear();
for (rr int i=1;i<=n-m+1;++i)
for (rr int j=1;j<=n-m+1;++j) uk[h[0][i][j]]=1;
for (rr int i=1;i<=n-m+1;++i)
for (rr int j=1;j<=n-m+1;++j)
if (uk[h[1][i][j]]) return 1;
return 0;
}
signed main(){
n=iut(),p1[0]=p2[0]=1;
for (rr int i=1;i<=n;++i) p1[i]=p1[i-1]*bas0;
for (rr int i=1;i<=n;++i) p2[i]=p2[i-1]*bas1;
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j) a[0][i][j]=iut();
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j) a[1][i][j]=iut();
rr int l=1,r=n;
while (l<r){
rr int mid=(l+r+1)>>1;
if (check(mid)) l=mid;
else r=mid-1;
}
return !printf("%d",l);
}
#二分,哈希 or dp#洛谷 4398 [JSOI2008]Blue Mary的战役地图的更多相关文章
- BZOJ 1567: [JSOI2008]Blue Mary的战役地图( 二分答案 + hash )
二分答案, 然后用哈希去判断... ------------------------------------------------------------------------- #include ...
- [JSOI2008]Blue Mary的战役地图(二分+哈希)
Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏.她正在设法寻找更多的战役地图以进一步提高自己的水平. 由于Blue Mary的技术已经达到了一定的高度,因此,对于用同一种打 ...
- B1567 [JSOI2008]Blue Mary的战役地图 二分答案+hash
一开始以为是dp,后来看了一下标签...二分答案?之前也想过,但是没往下想,然后之后的算法就顺理成章,先求出第一个地图的所有子矩阵的hash值,然后求第二个,在上一个地图例二分查找,然后就没了. 算法 ...
- 【矩阵哈希】【二分答案】【哈希表】bzoj1567 [JSOI2008]Blue Mary的战役地图
引用题解:http://hzwer.com/5153.html 当然,二分可以换成哈希表. #include<cstdio> #include<iostream> #inclu ...
- BZOJ1567 [JSOI2008]Blue Mary的战役地图 二分答案 哈希
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1567 题意概括 给出两个n*n的数字矩阵,问最大公共正方形边长. 题解 先二分答案一个m,对于每一 ...
- 洛谷P4254 [JSOI2008]Blue Mary开公司(李超线段树)
题面 传送门 题解 李超线段树板子 具体可以看这里 //minamoto #include<bits/stdc++.h> #define R register #define fp(i,a ...
- [JSOI2008]Blue Mary的战役地图——全网唯一一篇dp题解
全网唯一一篇dp题解 网上貌似全部都是哈希+二分(反正我是大概baidu了翻了翻)(还有人暴力AC了的..) 哈希还是相对于dp还是比较麻烦的. 而且正确性还有可能被卡(当然这个题不会) 而且还容易写 ...
- bzoj 1567: [JSOI2008]Blue Mary的战役地图【二分+hash】
二维哈希+二分 说是二维,其实就是先把列hash了,然后再用列的hash值hash行,这样可以O(n)的计算一个正方形的hash值,然后二分边长,枚举左上角点的坐标然后hash判断即可 只要base选 ...
- BZOJ1567 [JSOI2008]Blue Mary的战役地图(二分+二维hash)
题意 问边长为n的两个正方形中最大的相等子正方形.(n<=50) 题解 用到了二维hash,感觉和一维的不太一样. 对于列行有两个不同的进制数然后也是通过类似前缀和的方法差分出一个矩形的hash ...
- Luogu P4398 [JSOI2008]Blue Mary的战役地图 矩阵哈希
其实可以二分矩阵边长但是我太懒了$qwq$. 把每个子矩阵扔到$map$里,然后就没了 #include<cstdio> #include<map> #include<i ...
随机推荐
- linux和unix中的IO模型总结
高性能网络IO编程模型 一.I/O模型简介 在一个 linux 操作系统中,一般分为用户空间和内核空间. 用户空间一般就是我们进行应用程序编程的地方. 内核空间就是 linux 操作系统自己运行的一些 ...
- 【Android 逆向】【攻防世界】APK逆向
1. apk安装到手机,提示输入flag 2. jadx打开apk 定位到checkSN方法 public boolean checkSN(String userName, String sn) { ...
- 硬件开发笔记(八): 硬件开发基本流程,制作一个USB转RS232的模块(七):创建基础DIP元器件(晶振)封装并关联原理图元器件
前言 有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的.为了更好的表述封装设计过程,本文描述了创建晶振封装(DIP),将原理图的 ...
- Django关于StreamingHttpResponse与FileResponse响应文件或视频的下载请求
StreamingHttpResponse from django.http import StreamingHttpResponse StreamingHttpResponse(streaming_ ...
- tox运行报C901错误解决办法
# 报C901表示该函数太复杂! 解决办法 在函数上添加如下注释即可 # flake8: noqa: C901
- 使用go module导入本地包
go module是Go1.11版本之后官方推出的版本管理工具,并且从Go1.13版本开始,go module将是Go语言默认的依赖管理工具. 前提 假设我们有learngo和mypackage两个 ...
- 用图机器学习探索 A 股个股相关性变化
在本系列的前文 [1,2]中,我们介绍了如何使用 Python 语言图分析库 NetworkX [3] + Nebula Graph [4] 来进行<权力的游戏>中人物关系图谱分析. 在本 ...
- [前端] html和原生js实现鼠标拖动和触摸拖动以及点击后跟随鼠标移动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 闭关修炼180天 -- 手写SpringMVC框架(迷你版)
SpringMvc知识须知 MVC设计模式 Model(模型):模型包含业务模型和数据模型,数据模型⽤于封装数据,业务模型⽤于处理业 务. View(视图): 通常指的就是我们的 jsp 或者 htm ...
- MySQL之过滤条件
[一]筛选过滤条件 [1]查询语句 -- 查询当前表中的指定字段的数据 select id,name from emp where id > 3; [2]创建数据表 create databas ...