牛客寒假算法基础集训营3---J---- 处女座的比赛(规律暴力构造)

链接:https://ac.nowcoder.com/acm/contest/329/J
来源:牛客网

题目描述

经过了训练、资金等多方面的准备,处女座终于可以去比赛了!比赛采用codeforces赛制,也就意味着可以插人。现在有一道字符串的题目,处女座在room里看到一个用hash做的,于是决定把它hack掉。这个人的核心代码如下:

const int mod=9983;
mul[0]=p;mul[1]=q;mul[2]=r;
for (int i=0;i<26;i++)in_dex[i]=i*t+t;

int get_hash(char* s)//下标从1开始
{
    int ans=0,len=strlen(s+1);
    for (int i=1;i<=len;i++)
    ans=(ans*mul[i%3] + in_dex[s[i]-'a'])%mod;
    return ans;
}

现在处女座给你他想用来hack的第一个字符串 s1s1,和常数p,q,r,t,请你帮他找出第二个字符串s2s2,使得get_hash(s1)=get_hash(s2)get_hash(s1)=get_hash(s2)。

输入描述:

输入数据共两行,第一行为四个整数p,q,r,t,表示代码里的常数。

第二行为一个整数T,表示数据组数。

接下来一行,每行一个仅由小写字母构成的字符串s1s1,表示处女座想用来hack的字符串。

输出描述:

输出一行一个和s1s1不同的仅由小写字母构成的字符串s2s2,使得get_hash(s1)=get_hash(s2)get_hash(s1)=get_hash(s2)且|s2|20,000|s2|≤20,000。
示例1

输入

复制
123 456 789 101
3
afyo
cycw
cogw

输出

复制
cnztql
cnzak
cnzac

备注:

100p,q,r999100≤p,q,r≤999
2t9992≤t≤999且t是素数
1|s1|10,0001≤|s1|≤10,000
1T1,0001≤T≤1,000
数据保证p,q,r,t和s1s1均为随机生成

这套题不知不觉得就结束了,祝各位大佬们看到能愉快的AK本场比赛,同时也祝处女座早日能找到真正能够两心欢悦的小姐姐,前途似锦。

注:本次比赛中出现的所有图均为真实聊天截图,均为处女座本人所述,无任何PS部分。



思路:
突破口在题目中的mod,
mod=9983,
显然mod是很小的,我们分析如果长度为4的串,有26*26*26*26个,
然后暴力跑数据的时候发现枚举长度为4的所有字符串可以得到hash值为0~9983的至少两个。
那么我们就可以预处理枚举出长度为4个的所有字符串后,把每一个字符串加入到对应hash值的数组中,
然后当询问给出一个字符串的时候,会对应哈希值的数组中找到任意一个不等于当前字符串的string即可。
细节见AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/


const int mod=9983;
int p,q,r,t;
int mul[maxn];
int in_dex[maxn];
int get_hash(string s)//下标从1开始
{
     int ans=0,len=s.size();
    for (int i=0;i<len;i++)
    ans=(ans*mul[(i+1)%3] + in_dex[s[i]-'a'])%mod;
    return ans;
    // int ans=0,len=s.size();
    // for (int i=0;i<len;i++)
    // ans=(ans*mul[i%3] + in_dex[s[i]-'a'])%mod;
    // return ans;
}
string s;
std::vector<string> a[maxn];
int main()
{    
    
    cin>>p>>q>>r>>t;
    mul[0]=p;mul[1]=q;mul[2]=r;
    for (int i=0;i<26;i++)in_dex[i]=i*t+t;
    // pre
    
    // key
    for(int i=0;i<26;i++)
    for(int j=0;j<26;j++)
    for(int k=0;k<26;k++)
    for(int l=0;l<26;l++)
    {
        string s="";
        s+=char(i+'a');
        s+=char(j+'a');
        s+=char(k+'a');
        s+=char(l+'a');
        a[get_hash(s)].pb(s);
    }
            
        
    
    // main
    int T;
    cin>>T;
    while(T--)
    {
        cin>>s;
        int sum=get_hash(s);
        for(int i=0;i<a[sum].size();i++)
            if(a[sum][i]!=s)
            {
                cout<<a[sum][i]<<endl;break;
            }


    }

    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    }
    else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}
 

猜你喜欢

转载自www.cnblogs.com/qieqiemin/p/10325250.html