POJ 3274 HASH

题目链接:http://poj.org/problem?id=3274

题意+思路: 点击这里

补充:因为有减法运算,所以可能会造成运算后结果为负数,所以需要把结果统一转换成正数[不然数组下标访问不到负数位置],还有要先把0放入哈希表,不然会出现长度为1但是没有匹配的情况

比如:1 3

     7

结果为1,如果没把0放进哈希表则结果为0

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<time.h>
using namespace std;
typedef long long int LL;
const int MAXN=100000+5;
const int MAXK=30+5;
const int MOD=999991;
int Num[MAXN][MAXK]; //data storage
struct Node{
    int id,Next;
}Cow[MAXN];
int n,k,S[MAXN][MAXK];
int Scnt,Head[MOD];//hash table
void Init(){ //initialization
    memset(Head,-1,sizeof(Head));
    memset(S,0,sizeof(S));
    Scnt=0;
}
void AddNode(int HashN,int idx){
    Cow[Scnt].id=idx;
    Cow[Scnt].Next=Head[HashN];
    Head[HashN]=Scnt++;
}
bool cmp(int idx,int idy){ //compare two array
    for(int i=0;i<k;i++){
        if(S[idx][i]!=S[idy][i]){
            return false;
        }
    }
    return true;
}
int solve(){
    int ans=0;
    for(int i=0;i<=n;i++){ //insert 0 into the hash table first!
        int HashNum=0; //i==0 then insert 0 into the hash table because Data from 1 to n
        for(int j=0;j<k;j++){
            HashNum=((HashNum+S[i][j])+MOD)%MOD;
        }
        for(int j=Head[HashNum];j!=-1;j=Cow[j].Next){
            if(cmp(i,j)){
                ans=max(ans,i-j);
            }
        }
        AddNode(HashNum,i);
    }
    return ans;
}
void make_S(){//make array S
    for(int i=1;i<=n;i++){
        for(int j=0;j<k;j++){
            S[i][j]=S[i-1][j]+Num[i][j];
        }
    }
}
void make_C(){ //make array C
    for(int j=k-1;j>=0;j--){
        for(int i=1;i<=n;i++){
            S[i][j]-=S[i][0];
        }
    }
}
int main(){
#ifdef kirito
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif
    int start=clock();
    while(~scanf("%d%d",&n,&k)){
        Init();
        for(int i=1;i<=n;i++){
            int val;
            scanf("%d",&val);
            for(int j=0;j<k;j++,val/=2){
                Num[i][j]=val%2;
            }
        }
        make_S(); make_C();
        printf("%d\n",solve());
    }
#ifdef LOCAL_TIME
    cout << "[Finished in " << clock() - start << " ms]" << endl;
#endif
    return 0;
}
时间: 2024-08-06 16:05:50

POJ 3274 HASH的相关文章

Gold Balanced Lineup - poj 3274 (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]

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 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 3156 hash+记忆化搜索 期望dp

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m; #define N 32 #define mod 10007LL #define mod2 10000007 #define inf 0x3fffffff typedef long long ll; typedef double dd; int f[N]

poj 3349 hash的运用

哈希函数思想在查找中是非常重要的一个思想.在数据结构中我们学习的都只是一些简单的函数 比如: 相加取余 相乘取余 相除取余 .... 哈希函数在查找中可以在O(1)时间中查找到数据的位置. 哈希函数的关键在于函数的选取 , 然而不管选择怎么样的函数 , 一般都会存在冲突 , 但是如果函数选取得得当,那么冲突就会减小. poj 3349是一题简单的hash题 我们选取的函数是: 相加取余数 sort(b , b+6 ); x = 0; for(j = 0; j < 6; j++) x = (x*1

【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 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 examp

POJ 3349 HASH

题目链接:http://poj.org/problem?id=3349 题意:你可能听说话世界上没有两片相同的雪花,我们定义一个雪花有6个瓣,如果存在有2个雪花相同[雪花是环形的,所以相同可以是旋转过后相同]则输出“Twin snowflakes found.”,否则输出“No two snowflakes are alike.”. 思路:最简单的就是两两判断,但是这样的复杂度为O(n^2),TLE.所以我们要尽量减少判断次数,我们用把拥有6个瓣的雪花HASH成一个数字,只有两个雪花用有相同HA