恩,其实大家都没有报零,反正我是蒟蒻

为了纪念我第一次打过哈希,特此写一篇题解

题目描述

从前有一个的小矩阵,矩阵的每个元素是一个字母(区分大小写),突然有一天它发生了

变异,覆盖了整个二维空间,即不停自我复制产生相同的矩阵然后无隙放置。现在二维空间

已经被它占领了,但你只被告知了大小为R*C 空间的内容(可能包含不完整的原矩阵),为了

将它恢复原状,你需要找到满足条件的面积最小的原矩阵。

奇怪的是,同时有 T 个二维空间发生了变异,你需要尽快解决这些变异。

输入格式

第一行为一个整数T,表示二维空间数目。

接下来T 组数据。每组数据第一行包含两个数 R,C,表示你被告知的空间大小;接下

来 R 行,每行包含 C 个字母,表示你被告知的空间内容。

输出格式

对于每一组数据输出一行,每行只包含一个数,表示最小的原矩阵面积。

样例输入

2

2 5

ABABA

ABABA

2 8

ABCDEFAB

AAAABAAA

样例输出

2

12

数据范围与约定

对于前20%的数据 R<=20,C<=20;

对于前40%的数据R<=400,C<=100;

对于100%的数据R<=5000 ,C<=100,T<=50。

前20%的数据:大暴力,枚举原矩阵的左上角和右下角,暴力判断是否满足为原矩阵。

前40%的数据:考虑到一个性质,我们一定可以将原矩阵挪到给定矩阵的左上角考虑(循环

节的性质),那么就只用枚举原矩阵的右下角,用二维hash 可以判断两个矩形是否相等来优

化暴力,这样就能拿到40 分。

前100%的数据:

做法1:hash 暴力求出每一行可能的循环节长度,取公共的最小循环节长度即可,列同

理。将两次求得的最小循环节长度相乘即为答案。较慢,可能会超时。

做法 2:将每一行hash 为一个数,对得到的新数组直接跑KMP 求最小循环节长度,列

同理。将两次求得的最小循环节长度相乘即为答案。这就是std 做法。

一直觉得哈希是一个玄学玩意,特别怕冲突情况。但是如果哈希函数写得好,再加上人品不错,应该是可以水过去的

通常BKDRHash是比较优的

unsigned int BKDRHash(char *str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0; while (*str)
{
hash = hash * seed + (*str++);
} return (hash & 0x7FFFFFFF);
}

代码(其实就是存一个代码)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ui unsigned int
using namespace std; const int N=5000+5; int r,c,nxt[N];
ui H[N];
char s[N][N]; ui hash_x(int x){
ui seed=131;
ui hash=0;
for(int i=0;i<c;i++)
hash=hash*seed+s[x][i];
return hash;
}
ui hash_y(int x){
ui seed=131;
ui hash=0;
for(int i=0;i<r;i++)
hash=hash*seed+s[i][x];
return hash;
}
int getkmp_x(){
memset(nxt,0,sizeof(nxt));
int i=0,j=-1;
nxt[0]=-1;
while(i<r){
if(j==-1||H[i]==H[j]){
i++,j++;
nxt[i]=j;
}
else j=nxt[j];
}
return r-nxt[r];
}
int getkmp_y(){
memset(nxt,0,sizeof(nxt));
int i=0,j=-1;
nxt[0]=-1;
while(i<c){
if(j==-1||H[i]==H[j]){
i++,j++;
nxt[i]=j;
}
else j=nxt[j];
}
return c-nxt[c];
}
int getans_x(){
memset(H,0,sizeof(H));
for(int i=0;i<r;i++)
H[i]=hash_x(i);
return getkmp_x();
}
int getans_y(){
memset(H,0,sizeof(H));
for(int i=0;i<c;i++)
H[i]=hash_y(i);
return getkmp_y();
}
void solve(){
scanf("%d%d",&r,&c);
for(int i=0;i<r;i++)
scanf("%s",s[i]);
int x,y;
x=getans_x();
y=getans_y();
printf("%d\n",x*y);
}
int main(){
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
int t;
scanf("%d",&t);
while(t--)
solve();
return 0;
}

7.26机房报零赛——无尽的矩阵【kmp+hash】的更多相关文章

  1. android stdio 编译项目报Error:Failed to find target with hash string 'android-24

    android stdio 编译项目报Error:Failed to find target with hash string 'android-24 查看已有的SDK 设置项目的sdk为 25 an ...

  2. 2016 10 26考试 NOIP模拟赛 杂题

    Time 7:50 AM -> 11:15 AM 感觉今天考完后,我的内心是崩溃的 试题 考试包 T1: 首先看起来是个贪心,然而,然而,看到那个100%数据为n <= 2000整个人就虚 ...

  3. 26、从零写UVC驱动之分析描述符

    指令:lsusb 可以查看usb设备的描述符信息,当然lsusb指令要带一些参数 一个usb设备有多个config配置+设备描述符,一个config有多个接口和association.config描述 ...

  4. NOIP2016报零记

    其实,NOIP2016已经于10天之前就结束了,但是由于种种原因,没有写总结. 现在就来填上这个坑吧. DAY1: T1:一道简(kun)单(nan)的模拟,虽然ac,但是考试的时候总觉得怪怪的.并且 ...

  5. 4.26 省选模拟赛 T3 状压dp 差分求答案

    LINK:T3 比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到. 一看到题求删除点的最少个 可以使得不连通. 瞬间想到最小割 发现对于10分直接跑最小割即可. 不过想 ...

  6. 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Coin 概率+矩阵快速幂

    题目链接: https://nanti.jisuanke.com/t/17115 题意: 询问硬币K次,正面朝上次数为偶数. 思路: dp[i][0] = 下* dp[i-1][0] + 上*dp[i ...

  7. HDU 5015 233 Matrix(网络赛1009) 矩阵快速幂

    先贴四份矩阵快速幂的模板:http://www.cnblogs.com/shangyu/p/3620803.html http://www.cppblog.com/acronix/archive/20 ...

  8. [机房练习赛7.26] YYR字符串

    1  无尽的矩阵(matrix.c/cpp/pas) 1.1  题目描述 从前有一个的小矩阵,矩阵的每个元素是一个字母(区分大小写),突然有一天它发生了变异,覆盖了整个二维空间,即不停自我复制产生相同 ...

  9. NOI 2015 滞后赛解题报告

    报同步赛的时候出了些意外.于是仅仅能做一做"滞后赛"了2333 DAY1 T1离线+离散化搞,对于相等的部分直接并查集,不等部分查看是否在同一并查集中就可以,code: #incl ...

随机推荐

  1. selenium IDE录制脚本和自定义脚本-->Katalon Recorder(二)

    selenium IDE提供了两种生成脚本的方式:录制脚本和自定义脚本 录制脚本:1.打开firefox空白标签,在标签上输入需要录制脚本的网址:2.打开selenium IDE界面中的录制按钮(圆形 ...

  2. Python字符串的常用操作学习

    >>> name = "I love my job!" >>> name.capitalize() #首字母大写 'I love my job! ...

  3. 【转载】Unity3D研究院之IOS&Andoird使用Sharesdk遇到的坑

    这两天研究了一下ShareSDK,说实话挺好用的,但是还是有点坑的地方.那么雨松MOMO写下博文记录一下来我遇到的坑,嘿嘿. 大部分内容它的文档上已经说的很清楚了. http://wiki.share ...

  4. ASP.net MVC入门及Razor语法

    一.MVC入门: 1.MVC简介 约定大于配置 2.MVC访问流程 csthml模板(razor模板)就是简化HTML的拼接的模板,最终还是生成html给浏览器显示,不能直接访问cshtml文件. 二 ...

  5. 孤荷凌寒自学python第四十一天python的线程同步之Event对象

     孤荷凌寒自学python第四十一天python的线程同步之Event对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 鉴于Lock锁与RLock锁均宣告没有完全完成同步文件操作的问题,于 ...

  6. 用Margin还是用Padding?

    用margin还是用padding这个问题是每个学习CSS进阶时的必经之路. CSS边距属性定义元素周围的空间.通过使用单独的属性,可以对上.右.下.左的外边距进行设置.也可以使用简写的外边距属性同时 ...

  7. poj 2406 Power Strings (后缀数组 || KMP)

    Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 28859   Accepted: 12045 D ...

  8. BZOJ5157 [Tjoi2014]上升子序列 【树状数组】

    题目链接 BZOJ5157 题解 我们只需计算每个位置为开头产生的贡献大小,就相当于之后每个大于当前位置的位置产生的贡献 + 1之和 离散化后用树状数组维护即可 要注意去重,后面计算的包含之前的,记录 ...

  9. altera ip 核小究

    用quartus的MegaWizard工具生成一个乘法器multiplier,会在工程目录下产生 multiplier.qip    (可选) multiplier_bb.v  (可选) multip ...

  10. Command Pattern的简单介绍

    Command pattern 的角色有:Command(抽象命令).ConcreteCommand(具体命令) .Invoker(传达命令者) .receiver(接收命令者)Client(客户类, ...