poj 3007 Organize Your Train part II(字符串哈希)

来源:互联网 发布:php三元运算符 编辑:程序博客网 时间:2024/05/17 23:32

题目链接:http://poj.org/problem?id=3007

题意:给出一个字符串,从任意一个地方切开,分成两个字符串s1,s2,然后分别反转成s3,s4,然后将四个字符串任意组合(子串及其反串不可组合),求出所有不同的组合数。

如果用STL的话这题会超时,map什么的都用不了,就自己写了一个丑陋的哈希,设计的哈希函数也比较简单,47ms才过。

#include<iostream>#include<cmath>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;const int H=10007;const int maxn=10010;int hashTable[maxn],cnt;int T;char s[80],s1[80],s2[80],s3[80],s4[80],str[200];;struct node{char str[maxn];int next;}p[maxn];void initHash();int getHash(char *s);void addHash(char *s,int hashNum);bool searchHash(char *s);void strCut(char *s,char *s1,char *s2,int index);void strReverse(char *s1,char *s2);void strCat(char *s1,char *s2,char *str);int main(){#ifndef ONLINE_JUDGE    freopen("test.in","r",stdin);    freopen("test.out","w",stdout);#endif    scanf("%d",&T);    while(T--){    initHash();    scanf("%s",s);    if(!searchHash(s)) cnt++;    int len=strlen(s);    for(int i=1;i<=len-1;i++){    strCut(s,s1,s2,i);    strReverse(s1,s3);    strReverse(s2,s4);    strCat(s1,s4,str);if(!searchHash(str)) cnt++;strCat(s3,s2,str);if(!searchHash(str)) cnt++;strCat(s3,s4,str);if(!searchHash(str)) cnt++;strCat(s2,s1,str);if(!searchHash(str)) cnt++;strCat(s2,s3,str);if(!searchHash(str)) cnt++;strCat(s4,s1,str);if(!searchHash(str)) cnt++;strCat(s4,s3,str);if(!searchHash(str)) cnt++;    }    printf("%d\n",cnt);    }    return 0;}int getHash(char *s){int hash=0,len=strlen(s);for(int i=0;i<len;i++)hash=hash+s[i]*(i+1);return hash%H;}void initHash(){cnt=0;memset(hashTable,-1,sizeof(hashTable));}void addHash(char *s,int hashNum){int len=strlen(s);for(int i=0;i<len;i++)p[cnt].str[i]=s[i];p[cnt].str[len]='\0';p[cnt].next=hashTable[hashNum];hashTable[hashNum]=cnt;}bool searchHash(char *s){int hashNum=getHash(s);int next=hashTable[hashNum];for(int i=next;i!=-1;i=p[i].next){if(!strcmp(s,p[i].str))return true;}addHash(s,hashNum);return false;}void strCut(char *s,char *s1,char *s2,int index){int len=strlen(s);for(int i=0;i<index;i++)s1[i]=s[i];s1[index]='\0';for(int i=index;i<len;i++)s2[i-index]=s[i];s2[len-index]='\0';}void strReverse(char *s1,char *s2){int len=strlen(s1);for(int i=0;i<len;i++)s2[i]=s1[len-1-i];s2[len]='\0';}void strCat(char *s1,char *s2,char *str){int len1=strlen(s1);int len2=strlen(s2);int index=0;for(int i=0;i<len1;i++)str[index++]=s1[i];for(int j=0;j<len2;j++)str[index++]=s2[j];str[index]='\0';}


0 0
原创粉丝点击