您的位置:首页 > 编程语言 > C语言/C++

POJ 1840 Eqs.cpp 【 Hash 】

2012-09-19 23:59 477 查看
[b]题意:[/b]

给出一个不等式 a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0

问满足方程的 x1 x2 x3 x4 x5有多少个可能取值

输入a1 a2 a3 a4 a5 输出可能取值

[b]思路:[/b]

如果暴力 那么就是 100^5了~肯定会超时

所以..其实想要等式成立..则a3x33+ a4x43+ a5x53 = -(a1x13+ a2x23)

可以先求出等式左边的值 再看看是否存在等式右边的值

但是因为 x 取值为-50~50 不包括0

所以如果直接用数组下标对应x^3 然后用数组记录出现次数 那是不可能的

就可以用hash来完成了

这道题主要是用来练习hash表的..

然后还可以用离散化处理..

[b]Tips:[/b]

定义一个结构体 一个key值 一个sum值表示key出现了几次

数组的下标用key对某个数maxn取模来确定

如果这个数取模后的结果和之前某个数相同 则特征值一样了 就看key值是否一样~一样就sum++ 不一样就key = 这个数

查询的时候也是对某个数maxn取模..

然后看取模结果的key是否是这个数..

不是就无视它 是的话就可以找出这个值出现次数了

[b]Code:[/b]

View Code

#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define fabs(x) ((x)<0?(-x):(x))

const int maxn = 250000;

struct Hash
{
Hash(){key = 0, sum = 0;}
int key;
int sum;
}hash[maxn];

int main()
{
int i, j, k;
int a1, a2, a3, a4, a5;
int _tmp, tmp, tmp1, tmp2, ans;
int x[110];

for(i = -50; i < 0; ++i)
x[i+50] = i*i*i;
for(i = 1; i <= 50; ++i)
x[i+49] = i*i*i;

while(scanf("%d %d %d %d %d", &a1, &a2, &a3, &a4, &a5) != EOF)
{
memset(hash, 0, sizeof(hash));
tmp = ans = 0;

for(i = 0; i < 100; ++i) {
tmp = x[i]*a1;
for(j = 0; j < 100; ++j) {
tmp1 = tmp + x[j]*a2;
tmp2 = fabs(tmp1) % maxn;
while(hash[tmp2].key != tmp1 && hash[tmp2].sum != 0)
tmp2 = (tmp2+1)%maxn;
if(hash[tmp2].key == tmp1) {
hash[tmp2].sum++;
} else {
hash[tmp2].key = tmp1;
hash[tmp2].sum = 1;
}
}
}

for(i = 0; i < 100; ++i) {
_tmp = x[i]*a3;
for(j = 0; j < 100; ++j) {
tmp = _tmp + x[j] * a4;
for(k = 0; k < 100; ++k) {
tmp1 = tmp + x[k] * a5;
tmp2 = fabs(tmp1) % maxn;
while(hash[tmp2].key != -tmp1 && hash[tmp2].sum != 0)
tmp2 = (tmp2+1)%maxn;
//printf("key: %d sum: %d\n", hash[tmp1].key, hash[tmp1].sum);
ans += hash[tmp2].sum;
}
}
}

printf("%d\n", ans);
}
return 0;
}




[b]题目链接:http://poj.org/problem?id=1840[/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: