题目

求两个正方形矩阵的最大公共正方形矩阵边长


分析

第一种就是\(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的战役地图的更多相关文章

  1. BZOJ 1567: [JSOI2008]Blue Mary的战役地图( 二分答案 + hash )

    二分答案, 然后用哈希去判断... ------------------------------------------------------------------------- #include ...

  2. [JSOI2008]Blue Mary的战役地图(二分+哈希)

    Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏.她正在设法寻找更多的战役地图以进一步提高自己的水平. 由于Blue Mary的技术已经达到了一定的高度,因此,对于用同一种打 ...

  3. B1567 [JSOI2008]Blue Mary的战役地图 二分答案+hash

    一开始以为是dp,后来看了一下标签...二分答案?之前也想过,但是没往下想,然后之后的算法就顺理成章,先求出第一个地图的所有子矩阵的hash值,然后求第二个,在上一个地图例二分查找,然后就没了. 算法 ...

  4. 【矩阵哈希】【二分答案】【哈希表】bzoj1567 [JSOI2008]Blue Mary的战役地图

    引用题解:http://hzwer.com/5153.html 当然,二分可以换成哈希表. #include<cstdio> #include<iostream> #inclu ...

  5. BZOJ1567 [JSOI2008]Blue Mary的战役地图 二分答案 哈希

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1567 题意概括 给出两个n*n的数字矩阵,问最大公共正方形边长. 题解 先二分答案一个m,对于每一 ...

  6. 洛谷P4254 [JSOI2008]Blue Mary开公司(李超线段树)

    题面 传送门 题解 李超线段树板子 具体可以看这里 //minamoto #include<bits/stdc++.h> #define R register #define fp(i,a ...

  7. [JSOI2008]Blue Mary的战役地图——全网唯一一篇dp题解

    全网唯一一篇dp题解 网上貌似全部都是哈希+二分(反正我是大概baidu了翻了翻)(还有人暴力AC了的..) 哈希还是相对于dp还是比较麻烦的. 而且正确性还有可能被卡(当然这个题不会) 而且还容易写 ...

  8. bzoj 1567: [JSOI2008]Blue Mary的战役地图【二分+hash】

    二维哈希+二分 说是二维,其实就是先把列hash了,然后再用列的hash值hash行,这样可以O(n)的计算一个正方形的hash值,然后二分边长,枚举左上角点的坐标然后hash判断即可 只要base选 ...

  9. BZOJ1567 [JSOI2008]Blue Mary的战役地图(二分+二维hash)

    题意 问边长为n的两个正方形中最大的相等子正方形.(n<=50) 题解 用到了二维hash,感觉和一维的不太一样. 对于列行有两个不同的进制数然后也是通过类似前缀和的方法差分出一个矩形的hash ...

  10. Luogu P4398 [JSOI2008]Blue Mary的战役地图 矩阵哈希

    其实可以二分矩阵边长但是我太懒了$qwq$. 把每个子矩阵扔到$map$里,然后就没了 #include<cstdio> #include<map> #include<i ...

随机推荐

  1. Vue框架设计:性能权衡的艺术

    "框架设计里到处都体现了权衡的艺术." 当我们设计一个框架的时候,框架本身的各个模块之间并不是相互独立的,而是相互关联.相互制约的.因此作为框架设计者,一定要对框架的定位和方向拥有 ...

  2. django学习第一天---MVC和MTV框架,request对象的属性,url路由系统

    jinja2模板渲染简单使用 下载安装 pip install jinja2 使用示例 html文件中写法 <!DOCTYPE html> <html lang="zh-C ...

  3. 为Study.BlazorOne引入Study.Trade模块

    # 1.在Application项目中添加Trade的对应的包 默认的源多半是nuget.org 我们自己的模块,一般在我们自己的NuGet服务器 从"已安装"切换到"浏 ...

  4. 分布式事务框架seata入门

    一.简介 在近几年流行的微服务架构中,由于对服务和数据库进行了拆分,原来的一个单进程本地事务变成多个进程的本地事务,这时要保证数据的一致性,就需要用到分布式事务了.分布式事务的解决方案有很多,其中国内 ...

  5. SpringCloud Nacos

    1.Nacos简介 SpringCloud Alibaba 由来: 因为原先Spring Cloud 的许多组件都是对Netflix 公司的各种框架进行封装, 然后因为Netflix公司对后续更新的各 ...

  6. Java abstract 关键字使用

    1 package com.bytezreo.abstractTest; 2 3 /** 4 * 5 * @Description Abstract 关键字使用 6 * @author Bytezer ...

  7. 11、mysql的SQL执行顺序

    编写顺序 SELECT DISTINCT <select list> FROM <left_table> <join_type> JOIN <right_ta ...

  8. css移动端开发

    ​ 移动端浏览器主要对webkit内核兼容,现在的移动端主要针对手机端开发,移动端碎片化比较严重,分辨率和屏幕尺寸不一 调试方法 谷歌浏览器模拟手机调试 搭建本地web服务器,手机和服务器在同一个局域 ...

  9. Word中的公式复制到Visio中乱码问题

    将word中编辑好的公式复制到Visio中出现乱码问题 如图所示问题: 解决方案(Visio 选项 --> 高级 --> 显示 ->勾选禁用增强元文件优化) 具体的公式导入和解决操作 ...

  10. 对象遍历 Object.keys(obj).forEach(name=> {})

    Object.keys(props).forEach(name => { watch[name] = function (value) { this.columnConfig.update(na ...