標籤:包含 color 大小 實現 pre 否則 應該 模板題 line
題目描述
如題,給定N個字串(第i個字串長度為Mi,字串內包含數字、大小寫字母,大小寫敏感),請求出N個字串中共有多少個不同的字串。
友情提醒:如果真的想好好練習雜湊的話,請自覺,否則請右轉PJ試煉場:)輸入輸出格式
輸入格式:
第一行包含一個整數N,為字串的個數。
接下來N行每行包含一個字串,為所提供的字串。
輸出格式:
輸出包含一行,包含一個整數,為不同的字串個數。
輸入輸出範例輸入範例#1:
5abcaaaaabcabcc12345
輸出範例#1:
4
說明
時空限制:1000ms,128M
資料規模:
對於30%的資料:N<=10,Mi≈6,Mmax<=15;
對於70%的資料:N<=1000,Mi≈100,Mmax<=150
對於100%的資料:N<=10000,Mi≈1000,Mmax<=1500
範例說明:
範例中第一個字串(abc)和第三個字串(abc)是一樣的,所以所提供字串的集合為{aaaa,abc,abcc,12345},故共計4個不同的字串。
Tip: 感興趣的話,你們可以先看一看以下三題:
BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097
BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098
BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099
如果你仔細研究過了(或者至少仔細看過AC人數的話),我想你一定會明白字串雜湊的正確姿勢的^_^
最樸素的hash,過了80分。
代碼:
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int mod=88782431; 5 int n,l,ans; 6 unsigned int hash; 7 bool v[90000000]; 8 char ch[3000]; 9 int main(){10 scanf("%d",&n);11 for(int i=1;i<=n;i++){12 scanf("%s",&ch);13 l=strlen(ch);hash=1;14 for(int j=0;j<l;j++){15 hash=(hash*ch[j]*2351)%mod;16 }17 if(!v[hash]){18 v[hash]=1;19 ++ans;20 }21 }22 printf("%d\n",ans);23 return 0;24 }
結果:
#1AC2ms/102238kB #2AC3ms/102238kB#3AC2ms/19226kB#4AC16ms/102238kB
#5AC17ms/83347kB#6AC17ms/83316kB#7AC13ms/102238kB
#8WA122ms/102238kB//錯誤的答案。得分0 On line 1 column 3, read 19, expected 20.
#9WA122ms/102238kB//錯誤的答案。得分0 On line 1 column 4, read 1, expected 2.
#10AC122ms/102238kB
用稍正經點的hash就行。
代碼實現:
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int mod=29989; 5 unsigned int hash; 6 int n,l,a,b,ans,v[30000]; 7 int id[10010][1510]; 8 char ch[1510]; 9 bool bj(int x,int y){10 if(id[x][0]!=id[y][0]) return 0;11 for(int i=id[x][0];i>id[y][0]-5;i--)//比較五個就行,多了用時多,恩,其實比較最後一個了之後再比較長度和隨機一個(稍靠後)應該就行了。12 if(id[x][i]!=id[y][i]) return 0;13 return 1;14 }15 int main(){16 scanf("%d",&n);17 for(int i=1;i<=n;i++){18 scanf("%s",&ch);19 id[i][0]=strlen(ch);hash=1;20 for(int j=0;j<id[i][0];j++){21 hash=(hash*ch[j]*13)%mod;22 id[i][j+1]=hash;//把求hash的中間值存一下,其實也不用存這麼多。23 }24 while(v[hash]){//如果hash值一樣,看看字串是否相同。25 if(bj(v[hash],i)) break;26 hash++;27 }28 if(!v[hash]){//如果這個字串未出現過,就放下。29 v[hash]=i;30 ++ans;31 }32 }33 printf("%d\n",ans);34 return 0;35 }
hash模板題,當然用set或者map更簡單。
【模板】字串雜湊