前言
我只是凑数的。
正题
输入输出(建议无视)
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
解题思路
听真正的dalao讲的@神奇幂伟,大概就是把方程分成两半,如:
k1xp11+k2xp22=−k3xp33−k4xp44k1x1p1+k2x2p2=−k3x3p3−k4x4p4
然后用深搜前半段找出第一个的所有答案存进哈希表里(并且记录出现次数),然后再搜一次后半段寻找与前半段答案相反的话就算上方案
代码
#include<cstdio>
using namespace std;
const int maxn=4000037;//哈希个数
int n,m,hash[maxn],mid,a[7],p[7],num[maxn],S,ans;
int abs(int x)
{if (x<0) return -x;else return x;
}//绝对值,定位时使用
int hashmath(int x)
{return abs(x)%maxn;}//哈希函数
int locate(int x)//定位用
{int i=0,w=hashmath(x);//哈希函数while (i<maxn && hash[(w+i)%maxn]!=0 && hash[(w+i)%maxn]!=x)i++;//找到位置return (w+i)%maxn;//返回位置
}
void ins(int x)//加入
{int w=locate(x);//定位hash[w]=x;//改变值num[w]++;//记录出现次数
}
bool find(int x)//查找
{int w=locate(x);//位置if (hash[w]==x) return true;//返回else return false;
}
void dfs(int dep,int sum)//第一次搜
{if (dep>=mid+1){ins(sum);//插入return;}for (int i=1;i<=m;i++){ans=i;for (int j=2;j<=p[dep];j++) ans*=i;//即使x^pans*=a[dep];//得出结果dfs(dep+1,sum+ans);//搜}
}
void dfs2(int dep,int sum)
{if (dep>=n+1){if (find(-sum)) S+=num[locate(-sum)];//如果找到就记录return;}for (int i=1;i<=m;i++){ans=i;for (int j=2;j<=p[dep];j++) ans*=i;ans*=a[dep];dfs2(dep+1,sum+ans);}
}
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++){scanf("%d%d",&a[i],&p[i]);}mid=n/2;//分成两段dfs(1,0);dfs2(mid+1,0);printf("%d",S);
}