[hdu4495]二分,字符串hash,DP
题意:在一个有字母和数字组成的矩形里面找最大的等腰对称直角三角形,直角边分别平行于矩形边,对称的意思是对称轴两边的字符相同。
思路:首先考虑一种情况,三角形的直角边在右方和下方,对于其它情况可以通过旋转矩形来得到。这样令dp[i][j]表示直角点在(i,j)的最大三角形的直角边的长度,不难得到dp[i][j] = max(dp[i-1][j-1] + 2, len)。len表示从(i,j)向左和向上两个方向上的字符串"最长公共前缀"的长度。此类匹配问题用二分+hash来说简直妙不可言~
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <queue>#include <cmath>#include <algorithm>using namespace std;const int X = 12121;typedef unsigned long long uLL;int buf[567][567], img[567][567], dp[567][567];int n, m;void change() { for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { buf[m - j + 1][i] = img[i][j]; } } swap(n, m); for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { img[i][j] = buf[i][j]; } }}uLL H1[567][567], H2[567][567];uLL MUL[567];void init() { memset(H1, 0, sizeof(H1)); memset(H2, 0, sizeof(H2)); for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { H1[i][j] = H1[i][j - 1] * X + img[i][j]; H2[i][j] = H2[i - 1][j] * X + img[i][j]; } } MUL[0] = 1; for (int i = 1; i <= 500; i ++) { MUL[i] = MUL[i - 1] * X; }}bool chk(int x, int y, int len) { uLL row = H1[x][y] - H1[x][y - len] * MUL[len]; uLL col = H2[x][y] - H2[x - len][y] * MUL[len]; return row == col;}int solve() { init(); int ans = 0; for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { int L = 1, R = min(i, j); while (L < R) { int M = (L + R + 1) >> 1; if (chk(i, j, M)) L = M; else R = M - 1; } dp[i][j] = min(dp[i - 1][j - 1] + 2, L); ans = max(ans, dp[i][j]); } } return ans;}int main() {#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin);#endif // ONLINE_JUDGE int T; cin >> T; while (T --) { cin >> n >> m; for (int i = 0; i < n; i ++) { char s[567]; scanf("%s", s); for (int j = 0; j < m; j ++) { img[i + 1][j + 1] = s[j]; } } int ans = 0; for (int i = 0; i < 4; i ++) { ans = max(ans, solve()); change(); } cout << ans * (ans + 1) / 2 << endl; } return 0;} |
[hdu4495]二分,字符串hash,DP的更多相关文章
- CodeForces7D 字符串hash + dp
https://cn.vjudge.net/problem/20907/origin 长度是 n 的字符串 s,如果它自身是回文数,且它的长度为 的前缀和后缀是 (k - )-回文数,则它被称作 k- ...
- HDU 5763 Another Meaning dp+字符串hash || DP+KMP
题意:给定一个句子str,和一个单词sub,这个单词sub可以翻译成两种不同的意思,问这个句子一共能翻译成多少种不能的意思 例如:str:hehehe sub:hehe 那么,有**he.he** ...
- [CQOI2014][bzoj3507] 通配符匹配 [字符串hash+dp]
题面 传送门 思路 0x01 KMP 一个非常显然而优秀的想法:把模板串按照'*'分段,然后对于每一段求$next$,'?'就当成可以对于任意字符匹配就行了 对于每个文本串,从前往后找第一个可以匹配的 ...
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...
- Palindrome POJ - 3974 (字符串hash+二分)
Andy the smart computer science student was attending an algorithms class when the professor asked t ...
- POJ 1743 Musical Theme (字符串HASH+二分)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 15900 Accepted: 5494 De ...
- 【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】
[题目大意] 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. [字符串hash的小笔记] hash[i]=(hash[i-1]*p+idx(s[i]))%mod,idx为映射值,一般a.. ...
- AcWing:139. 回文子串的最大长度(字符串Hash + 前缀和 + 后缀和 + 二分)
如果一个字符串正着读和倒着读是一样的,则称它是回文的. 给定一个长度为N的字符串S,求他的最长回文子串的长度是多少. 输入格式 输入将包含最多30个测试用例,每个测试用例占一行,以最多1000000个 ...
- hdu 4622 Reincarnation 字符串hash 模板题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给定一个长度不超过2000的字符串,之后有不超过1e5次的区间查询,输出每次查询区间中不同 ...
- 字符串hash入门
简单介绍一下字符串hash 相信大家对于hash都不陌生 翻译过来就是搞砸,乱搞的意思嘛 hash算法广泛应用于计算机的各类领域,像什么md5,文件效验,磁力链接 等等都会用到hash算法 在信息学奥 ...
随机推荐
- Git敏捷开发--stash命令
save 执行git stash,默认以commit info保存当前的stash信息 当在某个commit下,执行多次stash时,无法友好地区分每个stash的改动.save 命令可以清晰地标识每 ...
- Java中集合的嵌套
集合的嵌套遍历 获取10个1-20之间的随机数,要求不能重复 键盘录入多个数据,以0结束,要求在控制台输出这多个数据的最大值. public static void main(String[] arg ...
- 关于log4j、jul、jcl、slf4j等等日志组件的理解
日志组件: 我们经常在开发项目的时候,需要打印记录项目过程中的一些日志.那我们经常大概会用到 log4j.jul.jcl.slf4j.simple.nop.logback 等等,那我们就详细介绍下这些 ...
- Metasploit学习笔记(一)
1.更新 apt-get update:更新源 apt-get upgrade:更新软件包 apt-get dist-upgrade:升级系统 2. Metasploit基础 2.1专业名词 Auxi ...
- [Windows] 如何用编程的方式格式化硬盘
If memory serves, you're looking for SHFormatDrive(). Use the Format method of the Win32_Volume clas ...
- java中CompletionService的使用
java中CompletionService的使用 之前的文章中我们讲到了ExecutorService,通过ExecutorService我们可以提交一个个的task,并且返回Future,然后通过 ...
- Android xUtils3.0使用手册(一)- 基础功能使用
xUtils3 其功能不得不说,简化了很多的开发步骤,可以说是非常好的开发工具,但是苦于没有完整的使用手册,下面是使用中的一些总结,不断完善. xUtils 版本 3.3.36 jar包下载地址 ht ...
- 一千行mysql笔记
原文地址:https://shockerli.net/post/1000-line-mysql-note/ /* Windows服务 */ -- 启动MySQL net start mysql -- ...
- 《LabVIEW 虚拟仪器程序设计从入门到精通(第二版)》一1.3 小结
本节书摘来自异步社区<LabVIEW 虚拟仪器程序设计从入门到精通(第二版)>一书中的第1章,第1.3节,作者 林静 , 林振宇 , 郑福仁,更多章节内容可以访问云栖社区"异步社 ...
- 日日算法:Dijkstra算法
介绍 Dijistra算法作为一种最短路径算法,可以用来计算一个节点到图上其他节点的最短距离. 主要是通过启发式的思想,由中心节点层层向外拓展,直到找到中点. 适用于无向图和有向图. 算法思想 假设我 ...