poj1840 Eqs(哈希表)

原题链接:Eqs

题意:求满足方程的解的个数

枚举打表吧

#include <cstring>
#include <iostream>
using namespace std;
const int MAX_S = 50 * 50 * 50 * 50 * 2;	//前两项和的最大值 
short ht[MAX_S * 2 + 1];	//*2 此处用short类型,内存勉强过了 
int main(){
	int a1, a2, a3, a4, a5, sum;
	while(cin >> a1 >> a2 >> a3 >> a4 >> a5 && (a1 || a2 || a3 || a4 || a5)){
		memset(ht, 0, sizeof(ht));
		for(int x1 = -50;x1 < 51;x1 ++){	if(x1 == 0) continue;
			for(int x2 = -50;x2 < 51;x2 ++){	if(x2 == 0) continue;
				sum = -1 * (a1 * x1* x1* x1 + a2 * x2* x2* x2) + MAX_S;	//将负的变为正的 
				++ ht[sum];	//将前两项的和的个数保存在数组中 
			}
		}
		int ans = 0;
		for(int x3 = -50;x3 < 51;x3 ++){	if(x3 == 0) continue;
			for(int x4 = -50;x4 < 51;x4 ++){	if(x4 == 0) continue;
				for(int x5 = -50;x5 < 51;x5 ++){	if(x5 == 0) continue;
					sum = a3 * x3* x3* x3 + a4 * x4* x4* x4 + a5 * x5* x5* x5 + MAX_S;
					if(sum >= 0 && sum < 2 * MAX_S && ht[sum]){	//sum<0或者sum小于前两项和的二倍说明不会相等 
						ans += ht[sum];
					}
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}


构造散列函数,用散列表空间上节省好多

#include <cstdio>
#include <cstring>
using namespace std;
const int MOD = 100003;	
const int MAX_N = 1000000 + 5;	
int hash[MOD + 1];	//hash[key]保存当前关键字key的对应data的下标 
int data[MAX_N], next[MAX_N];	//data[i]枚举的第i个前三项和的值,next[i]保存同一关键字下data的下标
int sz;
void insert(int x){
	data[sz] = x;
	int t = x > 0 ? x : -x;
	int key = (t / MOD + t % MOD) % MOD;	//哈希函数 
	next[sz] = hash[key];
	hash[key] = sz;
	sz ++;
}
int find(int x){
	int t = x > 0 ? x : -x;
	int key = (t / MOD + t % MOD) % MOD;
	int dex = hash[key], count = 0;
	while(dex > 0){ //同一关键下搜索 
		if(data[dex] == x)	count ++;
		dex = next[dex];
	}
	return count;
}
int main(){
	int a1, a2, a3, a4, a5;
	while(~scanf("%d%d%d%d%d", &a1, &a2, &a3, &a4, &a5)){
		int i, j, k, ans = 0;
		sz = 1;
		memset(hash, 0, sizeof(hash));	//初始化为每个关键子的下标都为0 
		for(i = -50;i <= 50;i ++){	if(!i)	continue;
			for(j = -50;j <= 50;j ++){	if(!j)	continue;
				for(k = -50;k <= 50;k ++){	if(!k)	continue;
					insert(a1 * i * i * i + a2 * j * j * j + a3 * k * k * k);
				}
			}
		}
		for(i = -50;i <= 50;i ++){	if(!i)	continue;
			for(j = -50;j <= 50;j ++){	if(!j)	continue;
				ans += find(-(a4 * i * i * i + a5 * j * j * j));
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值