此题还可以trie树判重
利用了c++ stl的优势
1.s.erase(s.begin(),s.end());//set全部清空的方式
2. memset(b2,0,sizeof(b2));//char数组全部清空 ,中间0表示ascall码
hash判重,set存
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<set>
#define debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long ll;
const int mod=1e9+7;
char a[105],b1[105],b2[105],t[10];
int len,ans;
set<ll> s;
void pan(char *b1,char *b2)
{
ll key=0;
int len1=strlen(b1),len2=strlen(b2);
for (int i=0;i<len1;i++) key=(key*29+(b1[i]-'a'+1))%mod;
for (int i=0;i<len2;i++) key=(key*29+(b2[i]-'a'+1))%mod;//字符串hash
if (s.count(key)==0) ans++,s.insert(key);//set判断是否已经出现
}
void rev(char *a)
{
int len=strlen(a);
char b;
for (int i=0;i<len/2;i++)//注意这里旋转,是要转前半部分,后部分如果再转就转回来了
{
b=a[i];a[i]=a[len-i-1];a[len-i-1]=b;
}
}
void work()
{
s.erase(s.begin(),s.end());//set的清空方式
ans=0;
scanf("%s",a);
len=strlen(a);
pan(t,a);
for (int i=1;i<len;i++)
{
memset(b1,0,sizeof(b1));
memset(b2,0,sizeof(b2));//char数组清空
for (int j=0;j<i;j++) b1[j]=a[j];
for (int j=i;j<len;j++) b2[j-i]=a[j];
rev(b2);pan(b1,b2);
rev(b1);pan(b1,b2);
rev(b2);pan(b1,b2);
rev(b1);
pan(b2,b1);
rev(b1);pan(b2,b1);
rev(b2);pan(b2,b1);
rev(b1);pan(b2,b1);
}
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while (T--) work();
return 0;
}
Trie树判重,注意trie树清空的问题,memset费时,
trie树判重可以通过他的特性做一些方便的用途
such as:给你100000个长度不超过10的单词。对于每一个单词,我们要判断他出没出现过,如果出现了,第一次出现第几个位置。
这题当然可以用hash来,但是我要介绍的是trie树。在某些方面它的用途更大。比如说对于某一个单词,我要询问它的前缀是否出现过。这样hash就不好搞了,而用trie还是很简单。
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<set>
#define debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
char a[105],b1[105],b2[105],t[10];
int len,ans,ch[400009][27],tot,val[400009];
inline int idx(char a)
{
return a-'a';
}
void pan(char *b1,char *b2)//trie树判重
{
int k=0,len1=strlen(b1),len2=strlen(b2);
for (int i=0;i<len1;i++)
{
int x=idx(b1[i]);
if (ch[k][x]) k=ch[k][x];
else
{
k=ch[k][x]=++tot;
memset(ch[k],0,sizeof(ch[k]));
}
}
for (int i=0;i<len2;i++)
{
int x=idx(b2[i]);
if (ch[k][x]) k=ch[k][x];
else
{
k=ch[k][x]=++tot;
memset(ch[k],0,sizeof(ch[k]));
}
}
if (val[k]) return;
val[k]=1;ans++;
}
void rev(char *a)
{
int len=strlen(a);
char b;
for (int i=0;i<len/2;i++)
{
b=a[i];a[i]=a[len-i-1];a[len-i-1]=b;
}
}
void work()
{
ans=tot=0;
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
scanf("%s",a);
len=strlen(a);
pan(t,a);
for (int i=1;i<len;i++)
{
memset(b1,0,sizeof(b1));
memset(b2,0,sizeof(b2));//char数组清空
for (int j=0;j<i;j++) b1[j]=a[j];
for (int j=i;j<len;j++) b2[j-i]=a[j];
rev(b2);pan(b1,b2);
rev(b1);pan(b1,b2);
rev(b2);pan(b1,b2);
rev(b1);
pan(b2,b1);
rev(b1);pan(b2,b1);
rev(b2);pan(b2,b1);
rev(b1);pan(b2,b1);
}
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while (T--) work();
return 0;
}