题目链接:点击打开链接
题目大意:一列 数串(likely more than 30 digits),分成几组,每组都是严格单减顺序。
题目分析:分析到最后,其实就是找重复最多的数就是组数,但是数的范围差别太大,一定对数进行处理。
接触到BKDR hash 先写借鉴大神的博客点击打开链接
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#define maxn 249997
int ans,hash[maxn];
unsigned int BKDRHash(char *str)
{
unsigned int seed=131 ;// 31 131 1313 13131 131313 etc..
unsigned int hash=0 ;
while(*str)
{
hash=hash*seed+(*str++);
}
return hash%maxn;
}
void solve(char *str)
{
int t;
while(*str=='0') str++;
t=BKDRHash(str);
if(hash[t]==-1) hash[t]=1;
else hash[t]++;
if(ans<hash[t]) ans=hash[t];
}
int main()
{
int n;
char str[50];
while(scanf("%d",&n)!=EOF)
{
memset(hash,-1,sizeof(hash));
getchar();
ans=1;
while(n--)
{
gets(str);
solve(str);
}
printf("%d\n",ans);
}
return 0;
}
题目总总结:
1.确定mod的数P,或者HASH 的数组范围P原则:P<=表长maxn(可事先进行,即hash后的范围),p为素数,或则至少不明显的合数,不含20以下的质因子
2.unsigned int 输出为%u = =
下面附上某牛的代码比我的代码的更加强,判错更严谨
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#define maxn 249997
using namespace std;
int hash[maxn],coun[maxn];
int ans;
unsigned int BKDRHash(char*str)
{
unsigned int seed=131 ;// 31 131 1313 13131 131313 etc..
unsigned int hash=0 ;
while(*str)
{
hash=hash*seed+(*str++);
//printf("*%u*\n",hash);
}
return(hash % maxn);
}
void hashit(char *str)
{
int k,t;
while(*str=='0') str++;
k=BKDRHash(str);//返回一个整型的状态
//printf("k=%d\n",k);观察maxn的范围
t=k%maxn;
while(hash[t]!=-1&&hash[t]!=k)
t=(t+10)%maxn;
if(hash[t]==-1) hash[t]=k,coun[t]=1;
else
{
//system("pause");
coun[t]++;
if(coun[t]>ans) ans=coun[t];
}
}
int main()
{
int N;
char str[50];
while(scanf("%d",&N)!=EOF)
{
memset(hash,-1,sizeof(hash));
ans=1;
getchar();
while(N--)
{
gets(str);
hashit(str);
}
printf("%d\n",ans);
}
}
其他相关资料借鉴:
真是非常好的学习资料
1.http://blog.csdn.net/v_JULY_v/article/details/6256463#comments
2.http://blog.csdn.net/v_july_v/article/details/7085669
3.http://blog.csdn.net/gdujian0119/article/details/6777239