杭电1800Flying to the Mars(简单哈希)

->题目请戳这里<-

题目大意:给n个数,表示n个人的等级,现在这n个人要去攻占火星,要坐扫把去,能坐在同一个扫把上的人要满足他们的等级严格递减,求最少的扫把数。

题目分析:就是求一个数字串的单调递减(递增)的子序列数,也就是求出现次数最多的那个数。给定数字范围是2^30,所以用哈希做。哈希函数定义的是每个数字各位平方和,跑了四百多毫秒,效率不是很高。。。

详情请见代码:

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int key,num;
}hash[6005];
int p = 2999;

int getkey(int x)
{
    int k = 0;
    int t;
    while(x)
    {
        t = x % 10;
        k += t * t;
        x /= 10;
    }
    return k % p;
}

int main()
{
    int i;
    int n,m;
    int key;
    while(scanf("%d",&n) != EOF)
    {
        memset(hash,-1,sizeof(hash));
        int mx = 0;
        int ans = 1;
        for(i = 0;i < n;i ++)
        {
            scanf("%d",&m);
            key = getkey(m);
            if(key > mx)
                mx = key;
            if(hash[key].key == -1)
            {
                hash[key].key = m;
                hash[key].num = 1;
            }
            else
            {
                int pos = key;
                while(hash[pos].key != -1)
                {
                    if(hash[pos].key == m)
                        break;
                    pos ++;
                }
                if(hash[pos].key == m)
                    hash[pos].num ++;
                else
                {
                    hash[pos].key = m;
                    hash[pos].num = 1;
                }
                if(mx < pos)
                    mx = pos;
                if(ans < hash[pos].num)
                    ans = hash[pos].num;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
//421MS	340K


你可能感兴趣的:(hash)