HDU 1880 魔咒词典(字符串hash)

原创 2016年05月30日 22:37:52

利用双hash来存储,之后利用二分来查找,复杂度O(nlogn)。就是难写了点,可能使用lower_bound会好一点

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 1e7+7;
#define N 101000
struct NODE
{
    char name[22];
    char spell[88];
}a[N];
struct haxi
{
    int x,y;
    int x1,y1;
    int num;
}b[N],d[N];
int a_len;
bool cmp(haxi a,haxi b)
{
    if(a.x==b.x)
        return a.y<b.y;
    else
        return a.x<b.x;
}
bool cmp1(haxi a,haxi b)
{
    if(a.x1==b.x1)
        return a.y1<b.y1;
    else
        return a.x1<b.x1;
}
haxi hash_fange(char *s,int len)
{
    int j;
    int tmp,tmp1;
    tmp=0;tmp1=0;
    for(j=0;j<len;j++)
    {
        tmp=tmp*131+s[j];
        tmp1=tmp1*141+s[j];
        tmp%=INF;tmp1%=INF;
    }
    haxi temp;
    temp.x=tmp;temp.y=tmp1;
    return temp;
}
void init()
{
    a_len=0;
    int i,len;
    char c;
    char tmp[100];
    while(scanf("%s",tmp)!=EOF)
    {
        if(tmp[0]=='@')
            break;
        else
        {
            len=strlen(tmp);
            for(i=1;i<len-1;i++)
                a[a_len].name[i-1]=tmp[i];
            a[a_len].name[len-2]='\0';
        }
        getchar();i=0;
        while((c=getchar())!='\n')
        {
            a[a_len].spell[i++]=c;
        }
        a[a_len].spell[i]='\0';
        a_len++;
    }
    //以上为输入//
    for(i=0;i<a_len;i++)
    {
        haxi temp;
        temp=hash_fange(a[i].name,strlen(a[i].name));
        d[i].x=temp.x;
        d[i].y=temp.y;
        temp=hash_fange(a[i].spell,strlen(a[i].spell));
        d[i].x1=temp.x;
        d[i].y1=temp.y;
        d[i].num=i;
        b[i]=d[i];
    }
    //以上为hash//
    sort(b,b+a_len,cmp);
    sort(d,d+a_len,cmp1);
}
void found(haxi x)
{
    int l=0,r=a_len-1,mid;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(x.x==b[mid].x)
        {
            if(x.y<=b[mid].y)
            {
                if(x.y==b[mid].y)
                {
                    printf("%s\n",a[b[mid].num].spell);
                    return;
                }
                else
                    r=mid-1;
            }
            else
                l=mid+1;
        }
        else
        {
            if(x.x<b[mid].x)
                r=mid-1;
            else
                l=mid+1;
        }
    }
    printf("what?\n");
}
void found_1(haxi x)
{
    int l=0,r=a_len-1,mid;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(x.x1==d[mid].x1)
        {
            if(x.y1<=d[mid].y1)
            {
                if(x.y1==d[mid].y1)
                {
                    printf("%s\n",a[d[mid].num].name);
                    return;
                }
                else
                    r=mid-1;
            }
            else
                l=mid+1;
        }
        else
        {
            if(x.x1<d[mid].x1)
                r=mid-1;
            else
                l=mid+1;
        }
    }
    printf("what?\n");
}
void solve()
{
    char s[110];
    char c;
    int n,len;
    haxi temp;
    scanf("%d",&n);
    getchar();
    while(n--)
    {
        c=getchar();
        if(c=='[')
        {
            scanf("%s",s);getchar();
            len=strlen(s);
            s[len-1]='\0';
            len--;
            temp=hash_fange(s,len);
            found(temp);
        }
        else
        {
            len=0;s[len++]=c;
            while((c=getchar())!='\n')
            {
                s[len++]=c;
            }
            s[len]='\0';
            temp=hash_fange(s,len);
            temp.x1=temp.x;
            temp.y1=temp.y;
            found_1(temp);
        }
    }
}
int main()
{
//    freopen("in.txt","r",stdin);
    init();
    solve();
//    for(int i=0;i<a_len;i++)
//        printf("%s %s\n",a[i].name,a[i].spell);
    return 0;
}

by:fange

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Hdu 1880 魔咒词典(hash链表)

题目1029:魔咒词典 时间限制:1000ms 内存限制:32 m 题目描述: 哈利波特在魔法学校的必修课之一就是学习魔咒。据说魔法世界有100000种不同的魔咒,哈利很难全...

HDU-1880-魔咒词典【哈希(Hash)+二分】

魔咒词典Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi...

hdu 1880 魔咒词典--字符串简单查找

思路: 使用两个二维数组分别存储Key和Value, 当找到Key,时输出Value; 找到Value时输出Key; 注意:1)此题使用STL 中map会 Memory Limit Exceede...

hdu 1880 魔咒词典

魔咒词典 Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis...

HDU 1880(魔咒词典)解题纠错

WA的原因是在输出“魔咒”时没有去除括号。

hdu 1880 魔咒词典(多种方法)

题目描述:     哈利波特在魔法学校的必修课之一就是学习魔咒。据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的...

HDU 1880 魔咒词典 (二分搜索)

Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒。据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的...

(HDU 1880)魔咒词典

Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒。据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的...

hdu acm 1880 魔咒词典

Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submissio...

HDU1880-魔咒词典

魔咒词典 Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 1880 魔咒词典(字符串hash)
举报原因:
原因补充:

(最多只允许输入30个字)