Poj 1186 方程的解数 (数据结构_Hash)

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

 题目大意:已知一个n元高次方程其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数.假设未知数1 <= xi <= M, i=1,,,n,1 <= n <= 6;1 <= M <= 150。求这个方程的整数解的个数。

 

解题思路:由于n和m特别小,可以通过枚举的方式来求解。枚举X1,X2..Xn/2,他们的和是一个定值,统计每个值出现的次数。再枚举Xn/2+1..Xn,它们的和也是定值,再看他的相反数出现几次,因为他们的和是0.最后统计结果就好。记录出现的次数用Hash,我的这段代码就是套模版,哈哈。

 

测试数据:

3

150
1  2
-1  2

1  2


3

100

1 1

1 1

1 1


代码:

#include <stdio.h>
#include <math.h>
#include <string.h>
#define maxm 5000000


int n,m,ans;
int k[10],p[10];
bool use[maxm*2]; //记录hash表是否被使用
int c[maxm*2];	  //表示前i出现的次数
int hash[maxm*2]; //保存hash值


int locate(int s){//has定位函数

    int temp = s;
    while(temp < 0) temp += maxm;
    while(temp >= maxm) temp -= maxm;
    while(use[temp] && hash[temp] != s){

        temp++;
        if(temp >= maxm) temp -= maxm;
    }
    return temp;
}
void insert(int s) {//has插入函数

    int pos = locate(s);
    hash[pos] = s;
    use[pos] = 1;
    c[pos]++;
}


void Count(int valhash,int now,int cnt){

	if (now == cnt) {

		insert(valhash);
		return;
	}

	
	int j,tp,i;
	for (j = 1; j <= m; ++j) {

		tp = k[now];
		for (i = 1; i <= p[now]; ++i) tp *= j;
		Count(valhash+tp,now+1,cnt);
	}
}
void Count2(int valhash,int now,int cnt){

	int i,j,tp,pos;
	if (now == cnt) {

		pos = locate(-valhash);
		if (hash[pos] == -valhash) ans += c[pos];
		return;
	}


	for (j = 1; j <= m; ++j) {

		tp = k[now];
		for (i = 1; i <= p[now]; ++i) tp *= j;
		Count2(valhash+tp,now+1,cnt);
	}
}


int main()
{
	int i,j,cnt,valhash;


	while (scanf("%d",&n) != EOF) {

		scanf("%d",&m);
		for (i = 0; i < n; ++i)
			scanf("%d%d",&k[i],&p[i]);
		
		//Hash
		memset(hash,0,sizeof(hash));
		ans = 0,cnt = n / 2;
		Count(0,0,cnt);
		Count2(0,cnt,n);
		printf("%d\n",ans);
					
	}
}

本文ZeroClock原创,但可以转载,因为我们是兄弟。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值