【邻接表字符串Hash】【HDU1800】Flying to the Mars

题意:

给你N个数字,带前导0,问出现最多的数字个数


思路:

读入,清楚前导0,Hash。

用邻接表字符串Hash有一下几点注意


string,不要memset,否则地址也没了,涉及到stl的东西,少用memset,类似还有vector;


assign截断字符串也是很黄很暴力的
直接assign(a.begin(),a.end) 即可

其实这种算法跟MAP 也没什么两样了。。。字符串HASH的更强大地方在于后缀的随机算法,这里不要过于纠结

而且MAP 效率高的多。。。

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
using namespace std;
int N;
struct edge
{
    string k;
    edge *next;
    int ans;
}E[4000];
struct node
{
    edge *first;
}Hash[10000];
  int ans=1;
void inputandhash()
{
    ans=1;
    int tot=0;
    memset(Hash,0,sizeof(Hash));
    string a;

    for(int i=1;i<=N;i++)
    {
        int temp=0,ok=1,p=0;
        cin>>a;
        for(int j=0;j<a.size();j++)
        {
            if(a[j]!='0') break;
            else p=j+1;
        }
        a.assign(a.begin()+p,a.end());
        for(int j=0;j<a.size();j++)
        {
            temp=(temp+(j+1)*(a[j]-'0'))%10000;
        }
        for(edge *p=Hash[temp].first;p;p=p->next)
        {
            if((p->k)==a) {
                            p->ans++;
                            ok=0;
                            if(p->ans>ans) ans=p->ans;
                            break;
                        }
        }
        if(ok)
        {
            E[tot].k.assign(a);
            E[tot].ans=1;
            E[tot].next=Hash[temp].first;
            Hash[temp].first=E+tot;
            tot++;
        }
    }
}
void init()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
}
int main()
{
  //  init();
	while(scanf("%d",&N)!=EOF)
    {
        inputandhash();
        printf("%d\n",ans);
    }
    return 0;
}




你可能感兴趣的:(【邻接表字符串Hash】【HDU1800】Flying to the Mars)