hdu 1496 Equations

题目链接: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;的个数。其中未知数的范围是[-100,100]; 常规的n^4肯定超时。这是使用了hash的算法。时间复杂度为n^2. 程序中的w[a*p[i]+b*p[j]+1000000]++;数组的下标表示状态,值表示个数。sum+=w[-(c*p[i]+d*p[j])+1000000];累计计算  其实可以这样理解前边两项的和为10数组+100的话是w[110]==1;要想满足要求 在后边的计数中应该为sum+=w[110]  而后两项的和c*x3^2+d*x4^2应为-10   所以就有了[-(c*p[i]+d*p[j])+1000000].

后边加上1000000是为了 把负值变成正的。

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cmath>
5 using namespace std;
6 int w[2000005];
7 int p[102];
8 int main()
9 {
10 int a,b,c,d,i,j,sum;
11 for(i=1;i<=100;i++)
12 p[i]=i*i;
13 while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF)
14 {
15 if(a>0&&b>0&&c>0&&d>0||a<0&&b<0&&c<0&&d<0)
16 {
17 printf("0\n");
18 continue;
19 }
20 memset(w,0,sizeof(w));
21 for(i=1;i<=100;i++)
22 for(j=1;j<=100;j++)
23 w[a*p[i]+b*p[j]+1000000]++;
24
25 sum=0;
26 for(i=1;i<=100;i++)
27 for(j=1;j<=100;j++)
28 sum+=w[-(c*p[i]+d*p[j])+1000000];
29 printf("%d\n",sum*16);
30 }
31 return 0;
32 }

优化算法(减少了内存):

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cmath>
5 using namespace std;
6 const int MAX=50000;
7 int w[MAX];
8 int f[MAX],g[MAX];
9 int p[102];
10 int hash(int k)
11 {
12 int t=k%MAX;
13 if(t<0)
14 t+=MAX;
15 while(f[t]!=0&&g[t]!=k)
16 t=(t+1)%MAX;
17 return t;
18 }
19 int main()
20 {
21 int a,b,c,d,i,j,sum,tt,gg;
22 for(i=1;i<=100;i++)
23 p[i]=i*i;
24 while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF)
25 {
26 if(a>0&&b>0&&c>0&&d>0||a<0&&b<0&&c<0&&d<0)
27 {
28 printf("0\n");
29 continue;
30 }
31 memset(w,0,sizeof(w));
32 memset(f,0,sizeof(f));
33 memset(g,0,sizeof(g));
34 for(i=1;i<=100;i++)
35 for(j=1;j<=100;j++)
36 {
37 tt=a*p[i]+b*p[j];
38 gg=hash(tt);
39 f[gg]++;
40 g[gg]=tt;
41 }
42
43 sum=0;
44 for(i=1;i<=100;i++)
45 for(j=1;j<=100;j++)
46 {
47 tt=-(c*p[i]+d*p[j]);
48 gg=hash(tt);
49 sum+=f[gg];
50
51 }
52 printf("%d\n",sum*16);
53 }
54 return 0;
55 }



posted @ 2012-02-28 16:30  我们一直在努力  阅读(182)  评论(0编辑  收藏  举报