2020牛客寒假算法基础集训营5 H.Hash

2020牛客寒假算法基础集训营5 H.Hash

题目描述

这里有一个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;
}

现给定一个长度为66的仅由小写字母构成的字符串ss和模数modmod,请找到字典序最小且大于ss的一个长度为66的仅由小写字母构成的字符串s’,使得其hash值和ss的hash相等。

输入描述:

多组用例,请处理到文件结束。(用例组数大约为1000组左右)

对于每组用例,输入一行,包含一个长度为66的仅由小写字母构成的字符串ss和模数 m o d ( 2 m o d 1 0 7 ) mod(2 \leq mod \leq 10^7) ,用空格隔开。

输出描述:

对于每组用例,如果存在如题目所述的s’,请输出s’,否则输出-1。

示例1

输入

abcdef 11

输出

abcdeq

从进制转换的角度不难发现,字符串是26进制,而其 h a s h hash 值正好为10进制,那么就很简单了,先将字符串 S S h a s h hash k k 算出来,因为 S S' h a s h hash k k' 与其取模相同且 字典序最小,那么 k = k + m o d k'=k+mod ,然后将其转换为26进制输出即可,有两个坑点:
1. S S' 长度小于 S S 时要在前面补 a 'a' ,因为字母 a 'a' h a s h hash 值恰为 0 0
2. S S' 长度大于 S S 时输出 1 -1

代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod;
string s;
void change(ll ans){
    string ss="";
    while(ans){
        ss=char(ans%26+'a')+ss;
        ans/=26;
    }
    if(ss.length()>6) {puts("-1");return ;}
    else if(ss.length()<6){
            int len=6-ss.length();
    for(int i=0;i<len;i++)
        ss='a'+ss;
    }
    cout<<ss<<endl;
}

int main()
{
    while(cin>>s>>mod){
        ll res=0;
        for(int i=0;i<6;i++){
            res=res*26+s[i]-'a';
        }
        ll ans=mod+res;
        change(ans);
    }
    return 0;
}
发布了288 篇原创文章 · 获赞 14 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43765333/article/details/104307820