poj 3274 哈希

http://poj.org/problem?id=3274

Description

Farmer John‘s N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been able to narrow down the list of features shared by his cows to a list of only K different features (1 ≤ K ≤ 30). For example, cows exhibiting
feature #1 might have spots, cows exhibiting feature #2 might prefer C to Pascal, and so on.

FJ has even devised a concise way to describe each cow in terms of its "feature ID", a single K-bit integer whose binary representation tells us the set of features exhibited by the cow. As an example, suppose a cow has feature ID = 13. Since 13 written
in binary is 1101, this means our cow exhibits features 1, 3, and 4 (reading right to left), but not feature 2. More generally, we find a 1 in the 2^(i-1) place if a cow exhibits feature i.

Always the sensitive fellow, FJ lined up cows 1..N in a long row and noticed that certain ranges of cows are somewhat "balanced" in terms of the features the exhibit. A contiguous range of cows i..j is balanced if each of the K possible
features is exhibited by the same number of cows in the range. FJ is curious as to the size of the largest balanced range of cows. See if you can determine it.

Input

Line 1: Two space-separated integers, N and K.

Lines 2..N+1: Line i+1 contains a single K-bit integer specifying the features present in cow i. The least-significant bit of this integer is 1 if the cow exhibits feature #1, and the most-significant bit is 1 if the cow
exhibits feature #K.

Output

Line 1: A single integer giving the size of the largest contiguous balanced group of cows.

Sample Input

7 3
7
6
7
2
1
4
2

Sample Output

4

题意:对于每头奶牛都有一个"feature ID",用一个整数表示,把这个数表示成K位二进制,对应位为1表示具有相应的特征,这样n头奶牛排成一排,求最长的连续区间,使得里面奶牛的全部K个特征个数达到平衡,即:

如果用sum[i][j] 表示前 i 头奶牛的第 j 个特征个数总和,则对于区间[a + 1, b],有

sum[b][1] - sum[a][1] = sum[b][2] - sum[a][2] = sum[b][j] - sum[a][j]   (1<= j <= K)

对表达式做变换得:

sum[b][1] - sum[b][2] = sum[a][1] - sum[a][2]

sum[b][1] - sum[b][j] = sum[a][1] - sum[a][j]   (1<= j <= K)

如果令c[i][j] = sum[i][j] - sum[i][1] (1<= j <= K)

则条件可以转换为:c[a] == c[b]

这样我们就可以在求的 c[i][j] (1<= i <= N, 1 <= j <= K)的基础上,对数组c[i](1 <= i <= N) hash,用开散列法(拉链法)求解即可。(摘自互联网)

哈希的结果是将哈希值相同的序列再进行比较,从而降低了时间复杂度。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=100005;
const int hashseed=99983;
int n,k;
int sum[maxn][35],c[maxn][35];
int head[hashseed+2],next[maxn];

int hash(int v[])
{
    int h=0;
    for(int i=1; i<=k; i++)
    {
        h=(h<<2)+(v[i]>>4)^(v[i]<<10);
    }
    h=(h+hashseed)%hashseed;
    return h;
}

int main()
{
    while(~scanf("%d%d",&n,&k))
    {
        memset(sum,0,sizeof(sum));
        for(int i=1; i<=n; i++)
        {
            int cnt;
            scanf("%d",&cnt);
            for(int j=1; j<=k; j++)
            {
                sum[i][j]=sum[i-1][j]+cnt%2;
                cnt/=2;
            }
        }
        int maxx=0;
        memset(head,-1,sizeof(head));
        for(int i=0; i<=n; i++)///一定要从0开始
        {
            for(int j=1; j<=k; j++)
            {
                c[i][j]=sum[i][j]-sum[i][1];
            }
            int h=hash(c[i]);
            bool flag=0;
            for(int p=head[h]; p!=-1; p=next[p])
            {
                int j;
                for(j=1; j<=k; j++)
                {
                    if(c[i][j]!=c[p][j])
                        break;
                }
                if(j>k)
                {
                    maxx=max(maxx,i-p);
                    flag=1;
                    break;
                }
            }
            if(flag==0)
            {
                next[i]=head[h];
                head[h]=i;
            }
        }
        printf("%d\n",maxx);
    }
    return 0;
}

时间: 2024-10-18 12:17:24

poj 3274 哈希的相关文章

线段树入门(poj 3274 3468 2528)

概念: 在一类问题中,我们需要经常处理可以映射在一个坐标轴上的一些固定线段,例如说映射在OX轴上的线段.由于线段是可以互相覆盖的,有时需要动态地取线段的并,例如取得并区间的总长度,或者并区间的个数等等.一个线段是对应于一个区间的,因此线段树也可以叫做区间树. 线段树常用于区间多次插入查询,经常改变数据. 而线段树的核心在于如何设计一个节点的信息 这里针对线段树的应用有三个方面: 1. 每次查询一个区间的最大差值(结点存放这个区间的最大最小值 3274) 2.不断修改区间内的数值,并查询区间的和

poj 3274 -- Gold Balanced Lineup

Gold Balanced Lineup Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12110   Accepted: 3553 Description Farmer John's N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been able to narrow down the list of features shared

poj 3274 Gold Balanced Lineup, 拉链式hash

sum[i][j] 表示从第1到第i头cow属性j的出现次数 所以题目要求等价为: 求满足 sum[i][0]-sum[j][0]=sum[i][1]-sum[j][1]=.....=sum[i][k-1]-sum[j][k-1] (j<i) 中最大的i-j 将上式变换可得到 sum[i][1]-sum[i][0] = sum[j][1]-sum[j][0] sum[i][2]-sum[i][0] = sum[j][2]-sum[j][0] ...... sum[i][k-1]-sum[i][0

哈希 poj 3274

n个牛 二进制最多k位 给你n个数 求max(j-i)&&对应二进制位的和相同 7    1  1  1  倒的 6    0  1  1 7    1  1  1 2    0  1  0 1    1  0  0 4    0  0  1 2    0  1  0 3 4 5 6  加起来一样 前缀和 - 第一列 然后就发现对应相等就是和相同 根据 和  hash 和   有小于0的 下标注意一下 1 #include<stdio.h> 2 #include<algo

POJ 3274 HASH

题目链接:http://poj.org/problem?id=3274 题意+思路: 点击这里 补充:因为有减法运算,所以可能会造成运算后结果为负数,所以需要把结果统一转换成正数[不然数组下标访问不到负数位置],还有要先把0放入哈希表,不然会出现长度为1但是没有匹配的情况 比如:1 3   7 结果为1,如果没把0放进哈希表则结果为0 #include<iostream> #include<algorithm> #include<cstring> #include<

【POJ 3274】Gold Balanced Lineup (stl map )设计hash表,处理碰撞

题目链接 题目链接 http://poj.org/problem?id=3274 题意 输入每头牛的特征的10进制,若i~j头牛中每个数位的特征相等则满足要求,求所有满足要求的j-i的最大值. 解题思路 抽屉原理,用前缀和处理每个数位即可. 直接暴力的话复杂度太大了,所以需要取巧的办法. 直接暴力求解是sum[i][p] - sum[j][p] == sum[i][0] - sum[j][0].其中i表示第i头牛,j表示第j头牛,p表示第p个特征,i > j. 取巧的办法:sum[i][p] -

POJ 2774 哈希+二分长度

思路:这题一看就知道是后缀数组做的了,好像以前做过,不过现在专攻哈希,所以就用哈希做了. 不过这题我真是要疯了!!! 刚开始写的就对了,然后二分while循环那忘了写等号了,然后一直WA,尼玛,然后自己居然给出一组样例: bbaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaa 这组的样例中的长度为6和7的时候哈希值居然不一样,然后输出了6:然后逗B的以为哈希是有bug的,然后改来改去,把哈希种子改成:131,1313,13131,131313,1313131,13131313,1

poj——3349 哈希加模拟

题目难点在于对两片雪花的比较,哈希可以加快搜索速度,防止超时,而对于如何逆时针和顺时针比较雪花是否相同便成为重点. 在这里给出两条公式: 设i为A.B的第i片叶子,j为B当前顺时针转过的格数 那么  A(i) ---> B( (i+j)%6 ) 设i为A.B的第i片叶子,j为B当前逆时针转过的格数 那么  A(i) ---> B( (5-i-j+6)%6 ) #include <iostream> using namespace std; #define mod 999983 ty

poj 1840 哈希

Eqs Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14093   Accepted: 6927 Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0 The coefficients are given integers from the interval [-50,50]. It i