题目链接:

https://vjudge.net/problem/POJ-3274

题目大意:

给定多头牛的属性,每头牛的属性由一个非负数表示,该数的二进制表示不会超过K位,它的二进制表示的每一位若为1则表示该牛有对应的第i种属性,若为0则表示没有该属性。

对于给定的牛的顺序,要求输出某一段子序列的长度,这个子序列中的牛的K个属性对应相加以后全部相等。

假设n=3, k = 3

输入的3个数变成的二进制分别为(a1, a2, a3), (b1, b2, b3), (c1, c2, c3)

设sum(i)为从第1个数到第i个数的属性和的序列

若从第2个数到第3个数的序列满足条件,则说明b1+c1 = b2+c2 = b3+c3,即sum(3)-sum(2)的序列每一位都相等

推广一下,若sum(i) = (a, b, c),sum(j) = (d, e, f),且i到j这个子序列满足条件,则说明(d, e, f) - (a, b, c) = (x, x, x),即(d, e, f) = (a + x, b + x, c + x)。每个序列中的数都减去序列中的最后一个数,得到(d - f, e - f, 0) = (a - c, b - c, 0)。因此只要判断两个完全转换过后的序列是否相同,就可以知道它们之间的原序列是否满足条件了。

所以解题的第一步是把原来的数转换为二进制序列,第二步是把二进制序列转换成sum序列,即逐步叠加,第三步是把每个sum序列都减去该序列的最后一个数,最后一步是把这些序列进行哈希,计算它们的最大差距。

有一点要注意,如果从第1个数到第i个数这段序列满足条件,即sum(i) - sum(0) = (x, x, x),则说明sum(i)的各个位都是相同的,因此需要在第三步之前先做这个判断,把符合条件的序列找出来,更新一下答案。所以在hash的时候先存入hash(0)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<cmath>
using namespace std;
const int maxn = + ;
const int mod = ;
int num[maxn][];
int n, k;
int maxlen;
struct hashtable
{
int x;
hashtable * next;
hashtable(){next = ;}
};
hashtable * Hash[mod]; bool Equal(int i, int j)
{
for(int c = ; c < k; c++)
if(num[i][c] != num[j][c])return false;
return true;
}
void Hash_Insert(int i)
//根据关键字key找hash位置, 找到位置后存i表示第i行
{
int key = ;
for(int j = ; j < k; j++)
key += j * num[i][j];
key = abs(key) % mod;
if(!Hash[key])//链表的第一个key
{
hashtable* p = new hashtable;
p -> x = i;
Hash[key] = p;
}
else//产生冲突
{
hashtable * p = Hash[key];
if(Equal(p->x, i))//如果和第i行相等
{
int dist = i - (p -> x);
maxlen = max(maxlen, dist);
}
else
{
while(p->next)//判断p->next是否存在,之后直接判断p->next存的行数和当前行数比较
{
if(Equal(p->next->x, i))
{
int dist = i - (p -> next -> x);
maxlen = max(maxlen, dist);
return;//不用存储i,直接返回,因为已经有和i一样的
}
p = p->next;
}
//地址冲突但是和每个冲突的都不相同
hashtable* temp = new hashtable;
temp->x = i;
p->next = temp;
}
}
return;
}
int main()
{
scanf("%d%d", &n, &k);
int x;
for(int i = ; i <= n; i++)
{
scanf("%d", &x);
for(int j = ; j < k; j++)
if(x & ( << j))num[i][j] = ;
for(int j = ; j < k; j++)
num[i][j] += num[i - ][j];
}
for(int i = ; i <= n; i++)
{
for(int j = ; j < k; j++)
num[i][j] -= num[i][];
}
for(int i = ; i <= n; i++)Hash_Insert(i);//从第0行开始
cout<<maxlen<<endl;
}

POJ-3274 Gold Balanced Lineup---hash经典题!的更多相关文章

  1. POJ 3274 Gold Balanced Lineup

    Gold Balanced Lineup Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10924 Accepted: 3244 ...

  2. POJ 3274 Gold Balanced Lineup(哈希)

    http://poj.org/problem?id=3274 题意 :农夫约翰的n(1 <= N <= 100000)头奶牛,有很多相同之处,约翰已经将每一头奶牛的不同之处,归纳成了K种特 ...

  3. poj 3274 Gold Balanced Lineup(哈希 )

    题目:http://poj.org/problem?id=3274 #include <iostream> #include<cstdio> #include<cstri ...

  4. POJ 3274 Gold Balanced Lineup 哈希,查重 难度:3

    Farmer John's N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been able to narrow ...

  5. Gold Balanced Lineup(hash)

    http://poj.org/problem?id=3274 ***** #include <stdio.h> #include <iostream> #include < ...

  6. poj3274 Gold Balanced Lineup(HASH)

    Description Farmer John's N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been abl ...

  7. POJ 3274:Gold Balanced Lineup 做了两个小时的哈希

    Gold Balanced Lineup Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13540   Accepted:  ...

  8. 哈希-Gold Balanced Lineup 分类: POJ 哈希 2015-08-07 09:04 2人阅读 评论(0) 收藏

    Gold Balanced Lineup Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13215 Accepted: 3873 ...

  9. 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

    1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 510  S ...

  10. 洛谷 P1360 [USACO07MAR]Gold Balanced Lineup G (前缀和+思维)

    P1360 [USACO07MAR]Gold Balanced Lineup G (前缀和+思维) 前言 题目链接 本题作为一道Stl练习题来说,还是非常不错的,解决的思维比较巧妙 算是一道不错的题 ...

随机推荐

  1. sql server 字符串转table

    -- ============================================= -- Author: gengc -- Create date: <2012-12-29> ...

  2. jenkins出现的问题

    1.增加服务器时 要修改时,,需要设置 2:出现这个问题是 执行了npm install node-sass

  3. MERGE批量增删查改数据

    MERGE优点: 在批量处理数据的时候,我可以用到merge一次完成数据处理. 示例代码一: MERGE INTO student AS t using ( AS age) s ON t.Age=s. ...

  4. 1.centos7 安装zookeeper

    1.安装jdk 1)查找jdk包: yum search java|grep jdk 2)安装: yum install -y java-1.8.0-openjdk.x86_64 2. 安装ZooKe ...

  5. STL之vector(不定长数组)

    vector就是一个不定长数组,另外它把一些常用操作“封装”在了vector类型内部.例如,若a是一个vector,可以用a.size()读取它的大小,a.resize()改变大小,a.push_ba ...

  6. Linux ps命令记录

    ps命令:查看当前系统进程状态 ps -a   显示当前所有进程ps -ax 显示没有控制终端的进程ps -u better   查看用户better的进程ps  aux|less 通过cpu和内存来 ...

  7. 关于vue路由嵌套遇到的坑~

    关键在于子路由中的path问题,path之前不要放/ <!DOCTYPE html> <html lang="en"> <head> <m ...

  8. Robot Framework常用库简介

    标准库 Robot Framework可以直接导入使用的库,包括: • Builtin:包含经常需要的关键字.自动导入无需import,因此总是可用的 • Dialogs:提供了暂停测试执行和从用户的 ...

  9. 多线程读写shared_ptrshared_ptr要加锁分析!学习笔记

     (shared_ptr)的引用计数本身是安全且无锁的,但对象的读写则不是,“因为 shared_ptr 有两个数据成员,读写操作不能原子化".使得多线程读写同一个 shared_ptr 对 ...

  10. Linpack之HPCG测试

    平台信息 Description: CentOS Linux release 7.6.1810 (Core) 注意事项 安装HPL之前需要配置好: CXX编译器(检查:c++ -v) MPICH 并行 ...