poj1186——方程的解数
2017-12-05 10:43
316 查看
题目大意:
,1 <= xi <= M, i=1...n(1 <= n <= 6;1 <= M <= 150)
输入:n
M
ki pi(共n行)
输出:整数解的个数
分析:折半搜索+哈希。暴力枚举超时,所以将方程分成两半,先枚举前一半的解,将总值哈希存储,然后枚举后一半看看是否和左值相等,若是则是一个解。
代码:转载自http://blog.csdn.net/sepnine/article/details/50154181
#include <iostream>
using namespace std;
const int HASHLEN=1000023;
const int MAXNODENUM=4000024;
int n,m,ans,e,tag;
int k[32],p[32];
int head[HASHLEN+10];
struct Node{
int val,cnt,nxt;
}edge[MAXNODENUM+10];
int hash_value(int x)
{
return x>0?x%HASHLEN:x%HASHLEN+HASHLEN;
}
void insert(int x)
{
int y=hash_value(x);
for(int i=head[y];i!=-1;i=edge[i].nxt){
if(edge[i].val==x){
++edge[i].cnt;
return ;
}
}
edge[e].val=x,edge[e].cnt=1,edge[e].nxt=head[y],head[y]=e++;
}
int lookup(int x)
{
int y=hash_value(x);
for(int i=head[y];i!=-1;i=edge[i].nxt)
if(edge[i].val==x)
return edge[i].cnt;
return 0;
}
void dfs(int cur,int end,int sum)
{
if(cur==end){
if(tag==0)
insert(sum);
else
ans+=lookup(-sum);
return ;
}
for(int i=1;i<=m;++i){
int t=1;
for(int j=0;j<p[cur];++j)
t*=i;
dfs(cur+1,end,sum+k[cur]*t);
}
}
int main()
{
memset(head,-1,sizeof(head));
//哈希邻接表的头结点
ans=e=0; //e为哈希邻接表中边结点个数
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)
scanf("%d%d",&k[i],&p[i]);
tag=0;
dfs(0,n/2,0);
tag=1;
dfs(n/2,n,0);
printf("%d",ans);
return 0;
}
,1 <= xi <= M, i=1...n(1 <= n <= 6;1 <= M <= 150)
输入:n
M
ki pi(共n行)
输出:整数解的个数
分析:折半搜索+哈希。暴力枚举超时,所以将方程分成两半,先枚举前一半的解,将总值哈希存储,然后枚举后一半看看是否和左值相等,若是则是一个解。
代码:转载自http://blog.csdn.net/sepnine/article/details/50154181
#include <iostream>
using namespace std;
const int HASHLEN=1000023;
const int MAXNODENUM=4000024;
int n,m,ans,e,tag;
int k[32],p[32];
int head[HASHLEN+10];
struct Node{
int val,cnt,nxt;
}edge[MAXNODENUM+10];
int hash_value(int x)
{
return x>0?x%HASHLEN:x%HASHLEN+HASHLEN;
}
void insert(int x)
{
int y=hash_value(x);
for(int i=head[y];i!=-1;i=edge[i].nxt){
if(edge[i].val==x){
++edge[i].cnt;
return ;
}
}
edge[e].val=x,edge[e].cnt=1,edge[e].nxt=head[y],head[y]=e++;
}
int lookup(int x)
{
int y=hash_value(x);
for(int i=head[y];i!=-1;i=edge[i].nxt)
if(edge[i].val==x)
return edge[i].cnt;
return 0;
}
void dfs(int cur,int end,int sum)
{
if(cur==end){
if(tag==0)
insert(sum);
else
ans+=lookup(-sum);
return ;
}
for(int i=1;i<=m;++i){
int t=1;
for(int j=0;j<p[cur];++j)
t*=i;
dfs(cur+1,end,sum+k[cur]*t);
}
}
int main()
{
memset(head,-1,sizeof(head));
//哈希邻接表的头结点
ans=e=0; //e为哈希邻接表中边结点个数
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)
scanf("%d%d",&k[i],&p[i]);
tag=0;
dfs(0,n/2,0);
tag=1;
dfs(n/2,n,0);
printf("%d",ans);
return 0;
}
相关文章推荐
- 【浅谈折半搜索】POJ1186[方程的解数]题解
- poj 1186 方程的解数(HASH,DFS)
- poj 1186 方程的解数【折半dfs+hash】
- POJ 1186 方程的解数
- POJ 1186 方程的解数 中文
- poj 1186 方程的解数 折半枚举+hash
- POJ 1186 方程的解数
- POJ 1186 方程的解数 [解题报告] Java
- POJ 1186 方程的解数
- poj 1186解方程(为什么双搜+hash)
- POJ1186 方程的解数
- poj 1186 方程的解数(线性探测再哈希)
- poj 1186:方程的解数
- 【暴力搜索】[POJ 1186]方程的解数
- poj 1186 方程的解数
- poj 1186 poj 1840 方程的解数 hash+枚举 (n/2)
- poj 1186 方程的解数 (hash+双向dfs)
- poj 2507 Crossed ladders 二分解方程
- POJ 1061 + POJ 2115 (求模线性方程)
- PKU 1186 方程的解数