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

算法很好想,也很好写,但是一开始我想的和最长公共子序列差不多的dp却不行(子矩阵是子串啊)。。。总的来说不是什么难题。

lower_bound是大于等于,返回的时候不用减一。

upper_bound是大于。

题干:

Description
Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏。她正在设法寻找更多的战役地图以进一步提高自己的水平。 由于Blue Mary的技术已经达到了一定的高度,因此,对于用同一种打法能够通过的战役地图,她只需要玩一张,她就能了解这一类战役的打法,然后她就没有兴趣再玩儿这一类地图了。而网上流传的地图有很多都是属于同一种打法,因此Blue Mary需要你写一个程序,来帮助她判断哪些地图是属于同一类的。 具体来说,Blue Mary已经将战役地图编码为n*n的矩阵,矩阵的每个格子里面是一个32位(有符号)正整数。对于两个矩阵,他们的相似程度定义为他们的最大公共正方形矩阵的边长。两个矩阵的相似程度越大,这两张战役地图就越有可能是属于同一类的。
Input
第一行包含一个正整数n。 以下n行,每行包含n个正整数,表示第一张战役地图的代表矩阵。 再以下n行,每行包含n个正整数,表示第二张战役地图的代表矩阵。
Output
仅包含一行。这一行仅有一个正整数,表示这两个矩阵的相似程度。
Sample Input Sample Output HINT
样例解释:
子矩阵: 为两个地图的最大公共矩阵 约定:
n<=
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 unsigned long long ull;
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 n,len = ;
ull mp[][],mp2[][],w[];
bool cmp(ull a,ull b)
{
return a < b;
}
void haxi(int x,int y,int l)
{
ull tot = ;
duke(i,x,x + l - )
{
duke(j,y,y + l - )
{
tot = tot * + mp[i][j];
}
}
w[++len] = tot;
}
ull haxi2(int x,int y,int l)
{
ull tot = ;
duke(i,x,x + l - )
{
duke(j,y,y + l - )
{
tot = tot * + mp2[i][j];
}
}
return tot;
}
int main()
{
read(n);
duke(i,,n)
duke(j,,n)
read(mp[i][j]);
duke(i,,n)
duke(j,,n)
read(mp2[i][j]);
int l = ,r = n;
while(l != r)
{
clean(w);
len = ;
int mid = (l + r) >> ;
duke(i,,n - mid + )
{
duke(j,,n - mid + )
{
haxi(i,j,mid);
}
}
sort(w + ,w + len + ,cmp);
int ok = ;
duke(i,,n - mid + )
{
duke(j,,n - mid + )
{
ull p = haxi2(i,j,mid);
int y = lower_bound(w + ,w + len + ,p) - w;
if(w[y] == p)
{
ok = ;
break;
}
}
if(ok == )
break;
}
if(ok == )
l = mid + ;
else
r = mid;
}
clean(w);
len = ;
duke(i,,n - l + )
{
duke(j,,n - l + )
{
haxi(i,j,l);
}
}
sort(w + ,w + len + ,cmp);
int ok = ;
duke(i,,n - l + )
{
duke(j,,n - l + )
{
ull p = haxi2(i,j,l);
int y = lower_bound(w + ,w + len + ,p) - w;
if(w[y] == p)
{
ok = ;
break;
}
}
if(ok == )
break;
}
if(ok == )
write(r);
else
write(r - );
return ;
}
/*
3
1 2 3
4 5 6
7 8 9
5 6 7
8 9 1
2 3 4
*/
/*
5
1 2 3 4 5
5 6 7 8 9
8 9 10 11 12
1 2 3 4 5
5 4 3 2 1
1 2 3 5 7
5 3 1 2 3
1 4 5 6 7
4 5 8 9 10
4 7 1 5 6
*/

B1567 [JSOI2008]Blue Mary的战役地图 二分答案+hash的更多相关文章

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

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

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

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

  3. bzoj1567: [JSOI2008]Blue Mary的战役地图

    将矩阵hash.s[0]忘了弄成0,输出中间过程发现了. hash.sort.判重.大概这样子的步骤吧. #include<cstdio> #include<cstring> ...

  4. BZOJ 1567: [JSOI2008]Blue Mary的战役地图

    1567: [JSOI2008]Blue Mary的战役地图 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1011  Solved: 578[Sub ...

  5. BZOJ 1567: [JSOI2008]Blue Mary的战役地图 矩阵二维hash

    1567: [JSOI2008]Blue Mary的战役地图 Description Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏.她正在设法寻找更多的战役地图以进一步提 ...

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

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

  7. [JSOI2008] [BZOJ1567] Blue Mary的战役地图 解题报告 (hash)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1567 Description Blue Mary最近迷上了玩Starcraft(星际争霸 ...

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

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

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

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

随机推荐

  1. PHP中的魔术方法和魔术常量

    看上去好像挺烦人,但只要通过例子测试一下,就明白了.不做测试,只是看,第二天还是不明白.当然我在抄其他人的日志,然后希望能是自己的理解就好,原文地址PHP的魔术方法和魔术敞亮简介和使用--LaraBo ...

  2. JS排序之快速排序

    JS排序之快速排序 一个数组中的数据,选择索引为(2/数组长度)的那个数据作为基数,数组中的其他数据与它对比,比它数值小的放在做数组,比它数值大的放在右数组,最后组合 左数组+基数+右数组,其中,左数 ...

  3. html5与css3入门知识点精炼

    <meta name = "keywords" content="…………"/>(网页搜索时要输入的关键字) <meta name = &qu ...

  4. 解决emlog默认导航不能修改的问题以及修改后台登录地址的方法

    修改默认导航 我们需要使用修改代码的方式来解决 首先找到admin/navbar.php文件 然后找到需要删除的几行代码: if ($type != Navi_Model::navitype_cust ...

  5. js 事件冒泡、事件捕获、stopPropagation、preventDefault

    转自:http://www.jb51.net/article/42492.htm (1)冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发. IE 5.5: ...

  6. 复习java基础第七天(反射)

    一:目标 Ø理解 Class 类 Ø理解 Java 的类加载机制 Ø学会使用 ClassLoader 进行类加载 Ø理解反射的机制 Ø掌握 Constructor.Method.Field 类的用法 ...

  7. OpenCv:椭圆上点的计算方程

    椭圆         椭圆(Ellipse)是平面内到定点F1.F2的距离之和等于常数(大于|F1F2|)的动点P的轨迹,F1.F2称为椭圆的两个焦点.其数学表达式为:                 ...

  8. Canopy聚类算法分析

          原文链接:http://blog.csdn.net/yclzh0522/article/details/6839643 Canopy聚类算法是可以并行运行的算法,数据并行意味着可以多线程进 ...

  9. [Intermediate Algorithm] - Everything Be True

    题目 所有的东西都是真的! 完善编辑器中的every函数,如果集合(collection)中的所有对象都存在对应的属性(pre),并且属性(pre)对应的值为真.函数返回ture.反之,返回false ...

  10. python 遍历xml所有节点

    1.xml文件 2.代码 #coding:utf-8 import xml import xml.etree.ElementTree as ET """ 实现从xml文件 ...