YBTOJ 2.2Hash 和 Hash 表
A.字符串匹配
板子题 详细解释见哈希学习笔记
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e9 + 7;
const int b = 37;
long long h[100721], prs = 0;
void hashe(string s) {
long long len = s.length();
long long ch = 1, sum = (long long)(s[0]) * b % N;
for (long long i = 1; i < len; ++i) {
ch = ch * b % N;
sum = (sum + (ch * s[i] * b % N)) % N;
}
h[++prs] = sum;
}
int main() {
long long n;
scanf("%lld", &n);
long long ans = n;
for (long long i = 1; i <= n; ++i) {
string s;
cin >> s;
hashe(s);
for (int j = 1; j < prs; ++j) {
if (h[j] == h[prs]) {
ans--;
break;
}
}
}
printf("%lld", ans);
return 0;
}
B.回文子串
为什么我在马拉车
当然哈希也能做 我们把这个字符串弄一个反过来的版本
然后二分一个长度来 check 即可
代码是马拉车(
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 0721;
int pdr[N];
int ans, mid, mr;
int main() {
char s1[N];
int cas = 0;
while (scanf("%s", s1)) {
if (s1[0] == 'E')
break;
memset(pdr, 0, sizeof(pdr));
ans = mid = mr = 0;
++cas;
string s;
int len = strlen(s1);
s += '~';
s += '#';
for (int i = 0; i < len; ++i) {
s += s1[i];
s += '#';
}
s += '$';
len = (len << 1) + 1;
for (int i = 1; i < len; ++i) {
if (i <= mr)
pdr[i] = min(pdr[(mid << 1) - i], mr - i);
else
pdr[i] = 1;
while (s[i + pdr[i]] == s[i - pdr[i]]) pdr[i]++;
if (pdr[i] + i - 1 > mr)
mr = pdr[i] + i - 1, mid = i;
}
for (int i = 1; i < len; ++i) ans = max(ans, pdr[i] - 1);
printf("Case %d: %d\n", cas, ans);
}
return 0;
}
C.对称正方形
主题思路和上题一样 二分正方形的最大边长
对于一个大对称正方形 小一圈同样也是对称正方形
主要是二维哈希判断
代码因为我写挂了并且调破防了所以就不贴了
D.单词背诵
非常经典的一道双指针 每次移动左指针就把上一个位置的单词出现次数--
如果那个单词出现次数变成了
至于如何判断相同单词 直接
点击查看代码
#include <bits/stdc++.h>
using namespace std;
map<string, int> word;
map<string, bool> flag;
int c[0x0d00], q[100721], f[100721];
int n, m, head, cnt, prs;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
string s;
cin >> s;
flag[s] = 1;
word[s] = ++head;
}
head = 0;
scanf("%d", &m);
for (int i = 1; i <= m; ++i) {
string s;
cin >> s;
if (flag[s]) {
cnt++;
flag[s] = 0;
}
q[++head] = word[s];
}
if (cnt == 0) {
printf("0\n0");
return 0;
}
printf("%d\n", cnt);
int l = 1, r = 0;
while (r <= head) {
while (1) {
if (prs == cnt)
break;
r++;
if (r > head)
break;
if (q[r] == 0)
continue;
if (c[q[r]] == 0) {
c[q[r]]++;
prs++;
if (prs == cnt)
break;
} else
c[q[r]]++;
}
if (prs == cnt) {
f[l] = r;
c[q[l]]--;
if (c[q[l]] == 0)
prs--;
l++;
}
}
int ans = 0x7fffffff;
for (int i = 1; i <= m; ++i) {
if (f[i] != 0)
ans = min(ans, f[i] - i + 1);
}
printf("%d", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】