您的位置:首页 > 其它

HDOJ1496 Equations(整数hash)

2017-09-11 16:32 323 查看

hash的基础思想:

1.哈希表(散列表)的基本原理:

使用一个下标范围比较大的数组来存储元素,一般通过设计一个函数(哈希函数,即散列函数),使得每个元素的关键字都与一个函数值(即数组下标)相对应,然后用该数组单元来存储对应元素。

2.hash表函数的构造:

最常见的方法:除余法

H(k ) = k mod p (p一般选取适当大的素数)

3.处理冲突

由于不能够保证每个元素的关键字与函数值是一一对应的,因此很有可能出现如下情况:“对于不同的元素关键字,Hash函数计算出了相同的函数值”,这就是产生了所谓的“冲突”。

换句话说,就是Hash函数把不同的元素分在了相同的下标单元。

常用方法:线性探测再散列技术

即:当 h(k)位置已经存储有元素的时候,依次探查 (h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中, S为 数组长度。

特别地,如果将数组扫描一圈仍未发现空单元,则说明哈希表已满,这会带来麻烦,但是,该情况完全可以通过扩大数组范围来避免。

4.hash表的基本操作

Hash表初始化(0或-1或其它)

哈希函数运算

插入元素(包含冲突解决)

定位(需考虑可能冲突的情况)

——————————————————————————————————————————————————————————

题意:

方程式为a*x1^2+b*x2^2+c*x3^2+d*x4^2=0

a, b, c, d 是 [-50,50] 区间内非零整数.

( x1,x2,x3,x4 ) 是[-100,100]区间内的非零整数。

问的是方程的解的情况有几种。

思路分析:

hash的妙处就在于实现了每一个元素的关键值都和数组的下标相对应。

先对x1和x2进行枚举,存在的存进hash表中,然后接下来枚举x3和x4,如果恰好和前面的为相反数,那么ans+上前面出现的次数.

由于求[-100,100]之间的非零整数,也就是说100*100*2=20000的一维数组就可以了。

PS:

用枚举1~100而负半区域不考虑,节省枚举数,最后答案因为四个数全部都是正的,而实际上都有每个数都有正有负,故答案*16

#include <stdio.h>
#include <algorithm>
#include <string.h>

using namespace std;

const int N = 2000005;

int main()
{
// freopen("in.txt", "r", stdin);
int a, b, c, d;
int Hash
;
while(~scanf("%d%d%d%d", &a, &b, &c, &d))
{
if(a * b > 0 && b * c > 0 && c * d > 0)
{
printf("0\n");
continue;
}
memset(Hash, 0, sizeof(Hash));
for(int i = 1; i <= 100; i ++)
for(int j = 1; j <= 100; j ++)
Hash[a * i * i + b * j * j + 1000000] ++;
int ans = 0;
for(int i = 1; i <= 100; i ++)
for(int j = 1; j <= 100; j ++)
ans += Hash[- c * i * i - d * j * j + 1000000];
printf("%d\n", 16 * ans); //我们计算的全是真的,实际上还有负的,只要在原结果*16即可。
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: