poj 1186 方程的解数
2014-03-29 10:53
357 查看
方程的解数
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
Sample Output
Source
Noi 01
初学hash做的第一道题,基本是照搬别人的程序。。。。。。看了一遍,自己敲了一遍,发现这是最普通的那种开放寻址加线性探查,然后期间用官方的pow函数死活不过,于是最后妥协了自己写的。。。。。
就是把算式剖开两半,然后对前面三个的结果做hash,之后对后面三个的结果的取反找hash,然后如果加起来是0那就是解。。感觉这个方法比较好,所以也记录一下。
Time Limit: 15000MS | Memory Limit: 128000K | |
Total Submissions: 6393 | Accepted: 2198 | |
Case Time Limit: 5000MS |
已知一个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; }
相关文章推荐
- poj1186——方程的解数
- poj 1186 方程的解数(HASH,DFS)
- poj 1186解方程(为什么双搜+hash)
- POJ1186 方程的解数
- poj 1186 poj 1840 方程的解数 hash+枚举 (n/2)
- POJ 1186 方程的解数 中文
- POJ 1186 方程的解数 [解题报告] Java
- POJ 1186 方程的解数
- poj 1186:方程的解数
- 【浅谈折半搜索】POJ1186[方程的解数]题解
- poj 1186 方程的解数(线性探测再哈希)
- poj 1186 方程的解数【折半dfs+hash】
- poj 1186 方程的解数 折半枚举+hash
- POJ 1186 方程的解数
- poj 1186 方程的解数 (hash+双向dfs)
- POJ 1186 方程的解数
- 【暴力搜索】[POJ 1186]方程的解数
- poj 2065 SETI 高斯消元解模线性方程
- POJ 2142 The Balance(扩展欧几里德解方程)
- 高斯消元解xor方程 poj1830