题目链接: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'; }