Description
已知一个n元高次方程:
其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数。
假设未知数1 <= xi <= M, i=1,,,n,求这个方程的整数解的个数。
1 <= n <= 6;1 <= M <= 150。
方程的整数解的个数小于2 31。
★本题中,指数Pi(i=1,2,...,n)均为正整数。
其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数。
假设未知数1 <= xi <= M, i=1,,,n,求这个方程的整数解的个数。
1 <= n <= 6;1 <= M <= 150。
方程的整数解的个数小于2 31。
★本题中,指数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
解题说明:1,爆搜150^6,双搜150^3*2
2,当我们查找一边的解时,结果很大,我们得用结构体存啊!那开多大?你是不是不知道,所以这个时候要hash表存了
3,刚开始用map超时了
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxl=10000007;
int m,n;
int ans=0;
int ki[7],pi[7];
struct num{
int acout,value;
}has[maxl];
int s_pow(int a,int k){
int nn=1;
while(k){
if(k&1){
nn*=a;
}
a*=a;
k>>=1;
}
return nn;
}
int serch(int y){
int y2=((y%maxl)+maxl)%maxl;
while(has[y2].acout!=0&&has[y2].value!=y){
y2++;
if(y2>=maxl)y2-=maxl;
}
return y2;
}
void insert(int y){
int temp=serch(y);
has[temp].acout++;
has[temp].value=y;
return ;
}
void dfs1(int x,int y){
if(x==n/2){
insert(y);
return ;
}
else{
for(int i=1;i<=m;i++)
dfs1(x+1,y+ki[x]*s_pow(i,pi[x]));
}
}
void dfs2(int x,int y){
if(x==n){
y=-y;
int y1=serch(y);
if(has[y1].value==y)ans+=has[y1].acout;
return;
}
else{
for(int i=1;i<=m;i++)
dfs2(x+1,y+ki[x]*s_pow(i,pi[x]));
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d%d",&ki[i],&pi[i]);
}
dfs1(0,0);
dfs2(n/2,0);
printf("%d\n",ans);
return 0;
}