牛客网训练1--------矩阵 (二份+二维矩阵hash)

本文介绍了一种使用hash算法来解决矩阵中寻找重复子矩阵的问题。通过对矩阵的每个子矩阵生成一个唯一的hash值,可以高效地检测是否存在相同的子矩阵。文章详细解释了hash算法的应用,并提供了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不懂hash的话:https://www.cnblogs.com/ALINGMAOMAO/p/10345850.html

思路:对于一个大矩阵的每一个子矩阵都对应着一个hash值k, 当k出现2次以上时就满足要求

   只是对长度进行二分就可以了。

收获:学会了hash算法

#include<iostream>
#include<map>
using namespace std;
#define ll long long
#define ull unsigned long long
const int maxn = 510;
const ull base1 = 131;
const ull base2 = 233;
int n, m;
char mp[maxn][maxn];
ull has[maxn][maxn];
ull p1[maxn], p2[maxn];
map<ull, int>mmp;

void init(){
    p1[0] = p2[0] = 1;
    for (int i = 1; i <= 505; ++i){
        p1[i] = p1[i - 1] * base1;
        p2[i] = p2[i - 1] * base2;
    }
}
void Hash(){
    has[0][0] = 0;
    has[0][1] = 0;
    has[1][0] = 0;
    for (int i = 1; i <= n;++i)
    for (int j = 1; j <= m; ++j){
        has[i][j] = has[i][j-1] * base1 + mp[i][j]-'a';
    }
    for (int i = 1; i <= n;++i)
    for (int j = 1; j <= m; ++j){
        has[i][j] = has[i - 1][j] * base2 + has[i][j];
    }
}

bool check(int x){
    mmp.clear();
    for (int i = x; i <= n; ++i)
    for (int j = x; j <= m; ++j){
        ull k = has[i][j] - has[i - x][j] * p2[x] - has[i][j - x] * p1[x] + has[i - x][j-x] * p1[x]*p2[x];
        mmp[k]++;
        if (mmp[k] >= 2)return true;
    }
    return false;
}

int main()
{
    init();
    while (cin >> n >> m){
        for (int i = 1; i <= n; ++i)
            cin >> (mp[i] + 1);
        Hash();
        int l = 0, r = 600, ans = 0;
        while (l <= r){
            int mid = (l + r) / 2;
            if (check(mid)){
                l = mid + 1;
                ans = mid;
            }
            else{
                r = mid - 1;
            }
        }
        cout << ans << endl;
    }
}

 

转载于:https://www.cnblogs.com/ALINGMAOMAO/p/10345873.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值