题意:在一个有字母和数字组成的矩形里面找最大的等腰对称直角三角形,直角边分别平行于矩形边,对称的意思是对称轴两边的字符相同。

思路:首先考虑一种情况,三角形的直角边在右方和下方,对于其它情况可以通过旋转矩形来得到。这样令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的更多相关文章

  1. CodeForces7D 字符串hash + dp

    https://cn.vjudge.net/problem/20907/origin 长度是 n 的字符串 s,如果它自身是回文数,且它的长度为 的前缀和后缀是 (k - )-回文数,则它被称作 k- ...

  2. HDU 5763 Another Meaning dp+字符串hash || DP+KMP

    题意:给定一个句子str,和一个单词sub,这个单词sub可以翻译成两种不同的意思,问这个句子一共能翻译成多少种不能的意思 例如:str:hehehe   sub:hehe 那么,有**he.he** ...

  3. [CQOI2014][bzoj3507] 通配符匹配 [字符串hash+dp]

    题面 传送门 思路 0x01 KMP 一个非常显然而优秀的想法:把模板串按照'*'分段,然后对于每一段求$next$,'?'就当成可以对于任意字符匹配就行了 对于每个文本串,从前往后找第一个可以匹配的 ...

  4. 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774

    Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...

  5. Palindrome POJ - 3974 (字符串hash+二分)

    Andy the smart computer science student was attending an algorithms class when the professor asked t ...

  6. POJ 1743 Musical Theme (字符串HASH+二分)

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 15900   Accepted: 5494 De ...

  7. 【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】

    [题目大意] 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. [字符串hash的小笔记] hash[i]=(hash[i-1]*p+idx(s[i]))%mod,idx为映射值,一般a.. ...

  8. AcWing:139. 回文子串的最大长度(字符串Hash + 前缀和 + 后缀和 + 二分)

    如果一个字符串正着读和倒着读是一样的,则称它是回文的. 给定一个长度为N的字符串S,求他的最长回文子串的长度是多少. 输入格式 输入将包含最多30个测试用例,每个测试用例占一行,以最多1000000个 ...

  9. hdu 4622 Reincarnation 字符串hash 模板题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给定一个长度不超过2000的字符串,之后有不超过1e5次的区间查询,输出每次查询区间中不同 ...

  10. 字符串hash入门

    简单介绍一下字符串hash 相信大家对于hash都不陌生 翻译过来就是搞砸,乱搞的意思嘛 hash算法广泛应用于计算机的各类领域,像什么md5,文件效验,磁力链接 等等都会用到hash算法 在信息学奥 ...

随机推荐

  1. lua 逻辑运算 and, or, not

    这边并非说lua低级,为了方便区分才这么写的. 高级语言中的逻辑运算符是&&,||,! a&&b : 当a和b都为真, 结果返回为真,当a或者b有一个为假,结果返回为假 ...

  2. 关于对vue-router的优化(详尽版)

    这两天总结了关于vue-router优化的几点技法,做个笔记 在基于vue的移动端app中,通过vue-router可以便捷的进入某一路由或回退到上一路由,但是若不对vue-router做相关优化处理 ...

  3. Golang交付至Kubernetes

    目录 0.前言 1.Go服务构建 1.1.制作Go服务镜像底包 1.2.制作slave基础镜像底包 1.2.1.Golang镜像 1.2.2.Docker镜像 2.创建golang流水线 3.流水线构 ...

  4. Springboot:员工管理之公共页面提取 高亮显示(十(5))

    把顶部和左侧的公共代码分别放到header.html和left.html中 顶部代码:resources\templates\header.html 主内容展示: <!DOCTYPE html& ...

  5. Java中的匿名对象代码实例

    /* 匿名对象:就是没有名字的对象. 匿名对象的应用场景: A:调用场景,仅仅只调用一次的时候. 注意:调用多次的时候,不合适. 那么,这种匿名调用有什么好处吗? 有,匿名对象调用完毕就是垃圾.可以被 ...

  6. pytorch中的前项计算和反向传播

    前项计算1 import torch # (3*(x+2)^2)/4 #grad_fn 保留计算的过程 x = torch.ones([2,2],requires_grad=True) print(x ...

  7. BlackNurse攻击:4Mbps搞瘫路由器和防火墙

    研究人员宣称,最新的知名漏洞BlackNurse,是一种拒绝服务攻击,能够凭借仅仅15到18Mbps的恶意ICMP数据包就将防火墙和路由器干掉. 该攻击会滥用Internet控制报文协议(ICMP)第 ...

  8. 编写C#程序的IDE

    编写C#程序,在Windows平台下,除了昂贵的Visual Studio.NET这个正宗的工具外,你还了解哪些? 听说有个Eclipse,IBM投钱开发的开源工具,有人也做了个for .NET的pl ...

  9. Codeforces 1291 Round #616 (Div. 2) C. Mind Control(超级详细)

    C. Mind Control You and your n−1 friends have found an array of integers a1,a2,-,an. You have decide ...

  10. 图论--SCC强连通缩点--Tarjan

    强连通缩点与双连通缩点大同小异,也就是说将强连通分支缩成一个点之后,没有强连通,成为有向无环图,在对图进行题目的操作. // Tarjan算法求有向图强连通分量并缩点 #include<iost ...