NYOJ 138 找球号(二) 【Hash】

  题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=138                                                             

  题目大意:N 次操作,每次可以是添加,也可以是询问,当是添加的时候,就往盒子里面添加球,询问的话就是每次询问编号为ki的球是否在盒子里,在的话就输出YES,否则输出NO。    


  分析:我们就是模拟,每次添加的时候把要加入的球放入盒子里,Hash处理一下,判处是否出现过,形成一一映射的关系。这样找的时候就不会TLE了。


  哈希其实就是一种映射,就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位。   


  字符串Hash,HDU 4622 求区间不相同子串的个数这个比上一个稍难点,也是模板题,需要预处理出每个子串对应的Hash值,然后用DP的思想求出每个区间的不相同子串的个数。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=462

CODE:

const double eps=0.0001;
const int HASH=1000007;
const int MAXN=1000010;
unsigned long long state[MAXN];//第i条边存放的数字
int next[MAXN],head[MAXN],top;//存图
int add(unsigned long long val)
{
    int h=val%HASH;
    state[top]=val;
    next[top]=head[h];
    head[h]=top++;
}
void init()//初始化
{
    top=0;
    memset(head,-1,sizeof(head));
    memset(state,-1,sizeof(state));
    memset(next,-1,sizeof(next));
}
char s[15];
int main()
{
    int t,n,x;
    scanf("%d",&t);
    init();
    while(t--)
    {
        scanf("%s%d",s,&n);
        if(s[0]=='A')
        {
            while(n--)
            {
                scanf("%d",&x);
                add(x);
            }
        }
        else
        {
            while(n--)
            {
                scanf("%d",&x);
                int kk=x%HASH,flag=0;
                for(int i=head[kk];i!=-1;i=next[i])
                {
                    if(x==state[i])
                    {
                        flag=1;
                        break;
                    }
                }
                if(flag)
                    printf("YES\n");
                else
                    printf("NO\n");
            }
        }
    }
}

你可能感兴趣的:(hash,nyoj)