题目链接: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
1501 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原创,但可以转载,因为我们是兄弟。