您的位置:首页 > 其它

poj 1186 方程的解数

2014-03-29 10:53 357 查看
方程的解数

Time Limit: 15000MSMemory Limit: 128000K
Total Submissions: 6393Accepted: 2198
Case Time Limit: 5000MS
Description

已知一个n元高次方程:



其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数。

假设未知数1 <= xi <= M, i=1,,,n,求这个方程的整数解的个数。

1 <= n <= 6;1 <= M <= 150。



方程的整数解的个数小于231。

★本题中,指数Pi(i=1,2,...,n)均为正整数。

Input

第1行包含一个整数n。第2行包含一个整数M。第3行到第n+2行,每行包含两个整数,分别表示ki和pi。两个整数之间用一个空格隔开。第3行的数据对应i=1,第n+2行的数据对应i=n。
Output

仅一行,包含一个整数,表示方程的整数解的个数。
Sample Input
3
150
1  2
-1  2
1  2

Sample Output
178

Source

Noi 01

初学hash做的第一道题,基本是照搬别人的程序。。。。。。看了一遍,自己敲了一遍,发现这是最普通的那种开放寻址加线性探查,然后期间用官方的pow函数死活不过,于是最后妥协了自己写的。。。。。

就是把算式剖开两半,然后对前面三个的结果做hash,之后对后面三个的结果的取反找hash,然后如果加起来是0那就是解。。感觉这个方法比较好,所以也记录一下。

#include <iostream>
#include<algorithm>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAX 4444444

using namespace std;
void left_ser(int d, int s);
void right_ser(int d, int s);
void insert_hash(int s);
int Hash(int s);
int getpow(int x, int p);

struct HASH{
int val;
int c;
}hash_t[MAX];
int use[MAX] = {0};
int mid, n, m, ans;
int k[11], p[11];

int main()
{
int i;
freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
//    for (i = 0;i < MAX;i ++)
//        hash_t[i].c = 0;
scanf("%d", &n);
scanf("%d", &m);
for (i = 0;i < n;i ++){
scanf("%d%d", &k[i], &p[i]);
}
ans = 0;
mid = n >> 1;
left_ser(0, 0);
right_ser(mid, 0);

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

void left_ser(int d, int s){
int i;
if (d == mid){
insert_hash(s);
return;
}
for (i = 1;i <= m;i ++){
left_ser(d+1, s + k[d]*getpow(i, p[d]));
}
}

void right_ser(int d, int s){
int pos, i;
if (d == n){
s = -s;
pos = Hash(s);
if (hash_t[pos].val == s){
ans += hash_t[pos].c;
}
return;
}
for (i = 1;i <= m;i ++){
right_ser(d + 1, s + k[d]*getpow(i, p[d]));
}
}

void insert_hash(int s){
int pos = Hash(s);
hash_t[pos].val = s;
hash_t[pos].c++;
use[pos] = 1;
}

int Hash(int s){
int temp = s;
while (temp >= MAX) temp -= MAX;
while (temp < 0) temp += MAX;
while(use[temp] && hash_t[temp].val != s){
temp ++;
if (temp >= MAX){
temp -= MAX;
}
}
return temp;
}

int getpow(int x, int p) {
int tmp = 1;
while (p) {
if (p&1)
tmp *= x;
x *= x;
p >>= 1;
}
return tmp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: