2020牛客寒假算法基础集训营5 H Hash
https://ac.nowcoder.com/acm/contest/3006/H
题目描述
这里有一个hash函数
const int LEN = 6;
int mod;
int Hash(char str[])
{
int res = 0;
for (int i = 0; i < LEN; i++)
{
res = (res * 26 + str[i] - 'a') % mod;
}
return res;
}
现给定一个长度为6的仅由小写字母构成的字符串s和模数mod,请找到字典序最小且大于s的一个长度为6的仅由小写字母构成的字符串s′,使得其hash值和s的hash相等。
思路
首先把上面的式子循环展开会发现是这么一个式子,
可以很明显的发现这是一个26进制的数字,求解方法也很简单。
我们另字符串为字典序最小且大于s并且hash值与其相同的字符串,让两个字符串做差值,可得
(k是整数)
既然要是字典序最小的,那么肯定相减之后结果也是最小的,又要大于它,所以上述差值一定等于mod,知道了而上面的式子又是一个26进制的数字,我们只需要将mod它转换成一个26进制数字后,加上原来的字符串就是结果了。(注意输出的是字母)
对于输出-1的情况,其实就是原来的6位的字符串加上mod的26进制表示后,位数超过6位了,就是-1了,解决方法就是统计进位,如果最后进位不为0说明会往前再进一位,超过6位
/*************************************************************************
> File Name: H.cpp
> Author: amoscykl
> Mail: amoscykl@163.com
> Created Time: 2020年02月13日 星期四 15时33分59秒
************************************************************************/
// 26进制问题
#include<bits/stdc++.h>
using namespace std;
char s[10];
char ans[10];
int mod;
int main()
{
while (~scanf("%s %d", s, &mod)){
for (int i = 0; i < 6; i++)ans[i] = s[i];
ans[6] = '\0';
int arr[10];
for (int i = 5; i >= 0; i--){
arr[i] = mod % 26;
mod /= 26;
}
if (mod != 0){
printf("-1\n");
}
else{
for (int i = 0; i < 6; i++)ans[i] -= 'a';
int up = 0;
for (int i = 5; i >= 0; i--){
ans[i] += arr[i];
ans[i] += up;
up = 0;
while (ans[i] > 25){
ans[i] -= 26;
up++;
}
}
if (up == 0){
for (int i = 0; i < 6; i++){
printf("%c", ans[i] + 'a');
}
printf("\n");
}
else printf("-1\n");
}
}
return 0;
}
本文来自博客园,作者:correct,转载请注明原文链接:https://www.cnblogs.com/correct/p/12861941.html

浙公网安备 33010602011771号