现在的位置: 首页 > 综合 > 正文

HDU 1800 Flying to the Mars 【字符串hash(ELFhash算法) / map】

2018年01月21日 ⁄ 综合 ⁄ 共 5314字 ⁄ 字号 评论关闭

Flying to the Mars

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11783    Accepted Submission(s): 3773

Problem Description


In the year 8888, the Earth is ruled by the PPF Empire . As the population growing , PPF needs to find more land for the newborns . Finally , PPF decides to attack Kscinow who ruling the Mars . Here the problem comes! How can the soldiers reach the Mars ? PPF
convokes his soldiers and asks for their suggestions . “Rush … ” one soldier answers. “Shut up ! Do I have to remind you that there isn’t any road to the Mars from here!” PPF replies. “Fly !” another answers. PPF smiles :“Clever guy ! Although we haven’t got
wings , I can buy some magic broomsticks from HARRY POTTER to help you .” Now , it’s time to learn to fly on a broomstick ! we assume that one soldier has one level number indicating his degree. The soldier who has a higher level could teach the lower , that
is to say the former’s level > the latter’s . But the lower can’t teach the higher. One soldier can have only one teacher at most , certainly , having no teacher is also legal. Similarly one soldier can have only one student at most while having no student
is also possible. Teacher can teach his student on the same broomstick .Certainly , all the soldier must have practiced on the broomstick before they fly to the Mars! Magic broomstick is expensive !So , can you help PPF to calculate the minimum number of the
broomstick needed .
For example :
There are 5 soldiers (A B C D E)with level numbers : 2 4 5 6 4;
One method :
C could teach B; B could teach A; So , A B C are eligible to study on the same broomstick.
D could teach E;So D E are eligible to study on the same broomstick;
Using this method , we need 2 broomsticks.
Another method:
D could teach A; So A D are eligible to study on the same broomstick.
C could teach B; So B C are eligible to study on the same broomstick.
E with no teacher or student are eligible to study on one broomstick.
Using the method ,we need 3 broomsticks.
……

After checking up all possible method, we found that 2 is the minimum number of broomsticks needed.

 

Input
Input file contains multiple test cases.
In a test case,the first line contains a single positive number N indicating the number of soldiers.(0<=N<=3000)
Next N lines :There is only one nonnegative integer on each line , indicating the level number for each soldier.( less than 30 digits);
 

Output
For each case, output the minimum number of broomsticks on a single line.
 

Sample Input
4 10 20 30 04 5 2 3 4 3 4
 
Sample Output
1 2
首次接触ELFhash算法,总结了下,本人更倾向去map,虽然耗时了点,--!。
ELFhash函数是对字符串的散列。它对于长字符串和短字符串都很有效,字符串中每个字符都有同样的作用,它巧妙地对字符的ASCII编码值进行计算,ELFhash函数对于能够比较均匀地把字符串分布在散列表中。

//ELFhash算法模板:
inline int ELFhash(char *key)
{
    unsigned long h = 0;
    unsigned long g;
    while( *key )
    {
        h =( h<< 4) + *key++;
        g = h & 0xf0000000L;
        if( g ) h ^= g >> 24;
        h &= ~g;
    }
    return h;
}

1.ELFhash算法解字符串hash:

#include<stdio.h> 
#include<memory.h>
#define MAXN 10000
int hash[MAXN],count[MAXN];
int max,n;
inline int ELFhash(char *key)
{
    unsigned long h = 0;
    unsigned long g;
    while( *key )
    {
        h =( h<< 4) + *key++;
        g = h & 0xf0000000L;
        if( g ) h ^= g >> 24;
        h &= ~g;
    }
    return h;
}

inline void hashit(char *str)
{
    int k,t;
    while(*str=='0') str++;
    k=ELFhash(str);
    t=k%MAXN;
    while(hash[t]!=k&&hash[t]!=-1)
    {
        t=(t+10)%MAXN;
    }
    if(hash[t]==-1) count[t]=1,hash[t]=k;
    else if(++count[t]>max) max=count[t];
}
int main()
{
    char str[100];
    while(scanf("%d",&n)!=EOF)
    {
        memset(hash,-1,sizeof(hash));
        for(max=1,gets(str); n>0; n--)
        {
            gets(str);
            hashit(str);
        }
        printf("%d\n",max);
    }
    return 0;
}

2,map解字符串hash,众数即是魔法扫帚的个数 
#include<cstdio>
#include<map>
using namespace std;
int main()
{
    int n,t,max;
    while(scanf("%d",&n)!=EOF)
    {
        map<int,int>mp; 
        max=0;
        while(n--)
        {
           scanf("%d",&t);
           mp[t]++;
           if(mp[t]>max)
           {
                max=mp[t];
           }
        }
        printf("%d\n",max);
    }
} 
网上搜了下ELFhash的解释,各种hash函数,mark一下:
// ELF Hash Function解析 
unsigned int ELFHash(char *str)
{
    unsigned int hash = 0;
    unsigned int x = 0;
while (*str)
{
    hash = (hash << 4) + (*str++);//hash左移4位,当前字符ASCII存入hash低四位。 
    if ((x = hash & 0xF0000000L) != 0)//如果最高的四位不为0,则说明字符多余7个,如果不处理,再加第九个字符时,第一个字符会被移出,因此要有如下处理。
    {
    
        hash ^= (x >> 24);//该处理,如果对于字符串(a-z 或者A-Z)就会仅仅影响5-8位,否则会影响5-31位,因为C语言使用的算数移位
    
    hash &= ~x;//清空28-31位。
    }
}
return (hash & 0×7FFFFFFF);//返回一个符号位为0的数,即丢弃最高位,以免函数外产生影响。(我们可以考虑,如果只有字符,符号位不可能为负)
}
// RS Hash Function
unsigned int RSHash(char* str)
{
    unsigned int b = 378551 ;
    unsigned int a = 63689 ;
    unsigned int hash = 0 ;
    while (*str)
    {
        hash = hash * a + (*str ++ );
        a *= b;
    }
    return (hash & 0x7FFFFFFF );
}

// JS Hash Function
unsigned int JSHash(char* str)
{
    unsigned int hash = 1315423911 ;
    while (*str)
    {
        hash ^= ((hash << 5 ) + (*str ++ ) + (hash >> 2 ));
    }
    return (hash & 0x7FFFFFFF );
}

// P. J. Weinberger Hash Function
unsigned int PJWHash(char* str)
{
    unsigned int BitsInUnignedInt = (unsigned int )( sizeof (unsigned int)*8 );
    unsigned int ThreeQuarters = (unsigned int )((BitsInUnignedInt*3 ) / 4 );
    unsigned int OneEighth = (unsigned int )(BitsInUnignedInt / 8 );
    unsigned int HighBits = (unsigned int )( 0xFFFFFFFF ) << (BitsInUnignedInt - OneEighth);
    unsigned int hash = 0 ;
    unsigned int test = 0 ;
    while (*str)
    {
        hash = (hash << OneEighth) + (*str ++ );
        if ((test = hash & HighBits) != 0 ) {
            hash = ((hash ^ (test >> ThreeQuarters)) & ( ~ HighBits));
        }
    }
    return (hash & 0x7FFFFFFF );
}

// ELF Hash Function
unsigned int ELFHash(char* str)
{
    unsigned int hash = 0 ;
    unsigned int x = 0 ;    while (*str)
    {
        hash = (hash << 4 ) + (*str ++ );
        if ((x = hash & 0xF0000000L ) != 0 ) {
            hash ^= (x >> 24 );
            hash &= ~ x;
        }
    }
    return (hash & 0x7FFFFFFF );
}

// BKDR Hash Function
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 & 0x7FFFFFFF );
}

// SDBM Hash Function
unsigned int SDBMHash(char* str)
{
    unsigned int hash = 0 ;
    while (*str)
    {
        hash = (*str ++ ) + (hash << 6 ) + (hash << 16 ) - hash;
    }
    return (hash & 0x7FFFFFFF );
}

// DJB Hash Function
unsigned int DJBHash(char* str)
{
    unsigned int hash = 5381 ;
    while (*str)
    {
        hash += (hash << 5 ) + (*str ++ );
    }
    return (hash & 0x7FFFFFFF );
}

// AP Hash Function
unsigned int APHash(char* str)
{
    unsigned int hash = 0 ;
    int i;
    for (i = 0 ;*str; i ++ )
    {
        if ((i & 1 ) == 0 )    {
            hash ^= ((hash << 7 ) ^ (*str ++ ) ^ (hash >> 3 ));
        }    else {
            hash ^= ( ~ ((hash << 11 ) ^ (*str ++ ) ^ (hash >> 5 )));
        }
    }
    return (hash & 0x7FFFFFFF );
}

抱歉!评论已关闭.