为了练习Hash,特定采用了杭电自带的分类列表http://acm.hdu.edu.cn/problemclass.php?id=64
本题采用暴搜貌似也能AC,在这里就不再给出了.
ps: 偏移量设置: a x1^2 + b x2^2 的取值范围 [-1000000,1000000]; 因此偏移量选择1000000即可
累积计数,可能出现多组数对的结果相同
第21行 b1[t1 + OFFSET]++; 需要累加,而不是 b1[t1 + OFFSET] =1;
代码如下:
1 #include <iostream>
2 #include <cmath>
3 #include <cstring>
4 using namespace std;
5
6 #define OFFSET 1000001
7
8 int b1[2000010];
9
10 long findA(int a,int b, int c, int d)
11 {
12
13 memset(b1,0,sizeof(b1));
14 long t1,t2,count=0;
15 int i,j;
16 for(i=1;i<=100;i++)
17 {
18 for(j=1;j<=100;j++)
19 {
20 t1 = a*(i*i) + b*(j*j);
21 b1[t1 + OFFSET]++; // 加入偏移量,以免越界
22 }
23 }
24 for(i=1;i<=100;i++)
25 {
26 for(j=1;j<=100;j++)
27 {
28 t2 = c*(i*i) +d*(j*j);
29 if(b1[OFFSET - t2]>0) count+=b1[OFFSET-t2]; //可以产生同一个结果的数对可能不止一个
30 }
31 }
32 return count;
33 }
34
35
36 int main()
37 {
38 int a,b,c,d;
39 while(cin>>a>>b>>c>>d && a && b && c && d)
40 {
41 if((a>0 && b>0 && c>0 && d>0)||(a<0 && b<0 && c<0 && d<0)) //逻辑加速,边间判断
42 cout<<0<<endl;
43 else
44 cout<<findA(a,b,c,d)*16<<endl;
45 }
46 return 0;
47 }