看题传送门:

http://acm.hdu.edu.cn/showproblem.php?pid=1496

题目大意:

给定a,b,c,d。a*x1^2+b*x2^2+c*x3^2+d*x4^2=0

其中x1~x4 在 [-100,100]区间内, a,b,c,d在[-50,50] 区间内。

求满足上面那个式子的所有解的个数。

思路:

这题用hash的思想很巧妙,先对x1和x2进行枚举,存在的存进hash表中,然后接下来枚举x3和x4,如果恰好和前面的为相反数,那么答案+上前面出现的次数.

提高效率的方法:

1.用枚举1~100而负半区域不考虑,节省枚举数,最后答案因为四个数全部都是正的,而实际上都有每个数都有正有负,故答案*16

2.把平方运算结果存下来。

3.位运算优化hash取模

4.同号的剪枝

普通的hash:

#include<cstdio>
#include<cstring>
const int MAXN=50*100*100*2+10;
int hash_pos[MAXN]; //positive
int hash_neg[MAXN]; //negative
int res[101];
int main()
{
int a,b,c,d ;
for(int i=1;i<=100;i++)
res[i]=i*i; while(~scanf("%d%d%d%d",&a,&b,&c,&d))
{
if(a>0 && b>0 && c>0 && d>0||a<0 && b<0 && c<0 && d<0)
{
printf("0\n");
continue;
}
memset(hash_pos,0,sizeof(hash_pos));
memset(hash_neg,0,sizeof(hash_neg)); for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
int x=res[i]*a+res[j]*b;
if(x >=0)
hash_pos[x]++;
else
hash_neg[-x]++;
}
} int cnt=0;
for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
int x=res[i]*c+res[j]*d;
if(x >0)
cnt+=hash_neg[x];
else
cnt+=hash_pos[-x];
}
} printf("%d\n",cnt<<4);
}
return 0;
}

采用开散列+位运算优化的取模运算!

//0 MS 476K
//By hr_whisper 2013/12/27
#include<cstdio>
#include<cstring>
const int mod=1<<15;
struct edge
{
int val,next,cnt;
}edge[mod]; int head[mod];
int len=0; inline int gethash(int x)
{
return (x+ mod) & (mod-1);
} inline void insert(int x)
{
int id=gethash(x);
for(int i=head[id]; i != -1;i=edge[i].next)
{
if(edge[i].val==x)
{
edge[i].cnt++;
return;
}
}
edge[len].cnt=1;
edge[len].next=head[id];
edge[len].val=x;
head[id]=len++;
} inline int search(int x)
{
int id=gethash(x);
for(int i=head[id] ; i!=-1;i=edge[i].next)
{
if(edge[i].val==x)
return edge[i].cnt;
}
return 0;
}
int res[101]; int main()
{
int a,b,c,d ;
for(int i=1;i<=100;i++)
res[i]=i*i; while(~scanf("%d%d%d%d",&a,&b,&c,&d))
{
if(a>0 && b>0 && c>0 && d>0||a<0 && b<0 && c<0 && d<0)
{
printf("0\n");
continue;
} memset(head,-1,sizeof(head));
len=0; for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
int x=res[i]*a+res[j]*b;
insert(x);
}
} int cnt=0;
for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
int x=res[i]*c+res[j]*d;
cnt+=search(-x);
}
} printf("%d\n",cnt<<4);
}
return 0;
}

最新文章

  1. iOS Hit-Test应用
  2. 《Entity Framework 6 Recipes》中文翻译系列 (46) ------ 第八章 POCO之领域对象测试和仓储测试
  3. C#基础——winform应用上传图片到SQLServer数据库
  4. iOS-网址集
  5. Servlet基础简单总结(上)
  6. 在javascript中如何取消事件冒泡
  7. EntityFramework常用查询
  8. 用正则表达式解析XML
  9. iTunes 安装终极解决方案
  10. GCC -Wall
  11. 福利:Axure 8.0 Pro 破解版下载
  12. direct-path插入方式提升性能的分析
  13. WebLogic使用总结(一)——WebLogic安装
  14. 在IE中下载Office2007文件时在对话框中下载文件变成ZIP文件的问题
  15. C/C++中的常量指针与指针常量(转)
  16. mongodb浅析
  17. 吴恩达深度学习笔记(deeplearning.ai)之卷积神经网络(CNN)(上)
  18. volley 之GsonRequest
  19. WPF ListView 使用GridView 带有Header 以及点击header排序 sort
  20. redis 新开端口号

热门文章

  1. ErrorSet
  2. jq实现回车键执行方法
  3. 简单的WINFORM窗口,体验WINFORM带来的快感
  4. scroll- 滑动条风格调整
  5. collapse折叠
  6. (转)修改 ubuntu 默认启动项
  7. MockServer jar包安装
  8. javascript脚本从载入浏览器到显示执行的过程解析
  9. Arch Linux下配置Samba
  10. 4.auto详解