处女座的比赛

【题目描述】

经过了训练、资金等多方面的准备,处女座终于可以去比赛了!比赛采用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 的第一个字符串 s1,和常数 p,q,r,t,请你帮他找出第二个字符串 s2,使得:get_hash(s1) = get_hash(s2)。

【输入描述】

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

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

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

【输出描述】

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

【样例】

示例1

输入
123 456 789 101
3
afyo
cycw
cogw
输出
cnztql
cnzak
cnzac

思路:

对长度 4 的小写字母的字符串共 475254 个(26*26*26*26),已经包括了 [0,9983] 的范围,因此对长度为 4 的字符串进行枚举即可,枚举时判断已构成的字符串的 hash 值是否与给的字符串的 hash 值相同,若相同则输出结果即可

【源代码】

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define PI acos(-1.0)
#define E 1e-6
#define INF 0x3f3f3f3f
#define N 100001
#define LL long long
const int MOD=9983;
using namespace std;
int p,q,r,t;
int mul[3];
int in_dex[26];
char str[N],temp[N];
int get_hash(char *s){
    int res=0;
    int len=strlen(s);
    for(int i=0;i<len;i++)
        res=(res*mul[(i+1)%3]+in_dex[s[i]-'a'])%MOD;
    return res;
}
int main()
{
    scanf("%d%d%d%d",&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;

    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%s",str);

        int Hash=get_hash(str);

        bool flag=true;
        for(int i=0;i<26&&flag;i++){
            temp[0]=(char)('a'+i);
            for(int j=0;j<26&&flag;j++){
                temp[1]=(char)('a'+j);
                for(int k=0;k<26&&flag;k++){
                    temp[2]=(char)('a'+k);
                    for(int l=0;l<26&&flag;l++){
                        temp[3]=(char)('a'+l);
                        temp[4]='\0';
                        if(Hash==get_hash(temp)){
                            if(strcmp(temp,str)!=0){
                                printf("%s\n",temp);
                                flag=false;
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值