HDU4300 Clairewd’s message 暴力/KMP算法

http://acm.hdu.edu.cn/showproblem.php?pid=4300

恶心的题目,英语渣又无力了。

题目大意:

先输入一个26长度的字符串表示a-z到字符串的一个对应关系表,然后输入第二个字符串,将其拆成str1+str2(可能不全)使得str2可以通过对应关系转为str1的最小长度字符串?(我也不晓得我在说啥了。。)

解题思路:

由于str1长度等于str2,因此可以从字符串一半之后开始暴,KMP同理,这道题暴力还比KMP快了一倍= =。

代码:

1暴力:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <ctime>
#include <algorithm>
#include <map>
#include <numeric>
#include <string>
#define time_seed srand((unsigned)time(NULL))
#define mset(x,y) (memset(x,y,sizeof(x)))
#define inf 0x3fffffff
#define pf printf
#define pf1(x) printf("%d\n",x)
#define pf2(x,y) printf("%d %d\n",x,y)
#define pf3(x,y,z) printf("%d %d %d\n",x,y,z)
#define sf scanf
#define sf1(x) scanf("%d",&x)
#define sf2(x,y) scanf("%d%d",&x,&y)
#define sf3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define fr(i,x,y) for(int i=x ; i<y ;++i)
#define _fr(i,x,y) for(int i=x ; i>y ;--i)
#define ls (id<<1)
#define rs ((id<<1)|1)
typedef long long ll;
using namespace std;
const int N=100024;
char rea[N],sec[N];
char S[81],rS[81];
int len;
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        sf("%s%s",S,sec);
        fr(i,0,26)  rS[S[i]-'a']=i+'a';
        rS[26] = 0;
        memcpy(rea,sec,sizeof(sec));
        len = strlen(sec);
        for(int i=0;i<len;++i) sec[i] = rS[sec[i]-'a'];
        int i;
        for(i=((len+1)>>1);i<len;++i)
        {
            int k = i;
            for(int j=0;k<len;++j, ++k)
            {
                if(sec[j] != rea[k])
                 break;
            }
            if(k==len)
            {
                fr(j,0,i)putchar(rea[j]);
                fr(j,0,i)putchar(sec[j]);
                putchar('\n');
                break;
            }
        }
        if(i==len)
        {
            pf("%s%s\n",rea,sec);
        }
    }
    return 0;
}

2KMP:

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAXN 100100
#define INF 0x7fffffff
#define eps 1e-10
#define MAX(x,y) ((x)>(y)? (x):(y))
#define MIN(x,y) ((x)<(y)? (x):(y))
#define MEM(a) (memset((a),0,sizeof(a)))
#define FRE freopen("input.txt","r",stdin)
using namespace std;

int next[100005];
char tran[27];
char s[MAXN],s2[MAXN];


int kmp(char *s,char *t)
{
    int slen=strlen(s),tlen=strlen(t);
    next[0]=-1;
    int i=0,j=-1;
    while(i<tlen)
    {
        if(j==-1 || t[i]==t[j])
        {
            i++; j++;
            next[i]=j;
        }
        else
            j=next[j];
    }
	i=j=0;
	while(i<slen && j<tlen)
	{
		 if(j==-1 || s[i]==t[j])
		 {
			  i++; j++;
			  if(i==slen)
				  return j;
		 }
		 else
			  j=next[j];
	}
	return 0;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",tran);
        scanf("%s",s);
        int len=strlen(s);
        strcpy(s2,s+(len+1)/2);
        printf("%s",s);
        for(int i=0;s[i];i++)
            for(int j=0;j<26;j++)
                if(s[i]==tran[j])
                {
                    s[i]='a'+j;
                    break;
                }
        int pos=kmp(s2,s);
        for(int i=pos;i<len-pos;i++)
            printf("%c",s[i]);
        printf("\n");
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值