hdu 1496(hash)

这个题挺水的,但是一开始想的比较复杂。

一开始就准备暴力剪枝,分为两种情况1,3(三个同号一个异号)和2,2(两个分别同号)

但是写了写再加上别的小地方的剪枝比较复杂。

果断放弃了。

然后搜了之后还是只能感叹 磨刀不误砍柴工。

水题是要动脑子的呀!

这个题的思路就是由判断abcd相加等于零变为判断ab与cd的和的相反数相等。

这样复杂度很神奇的减少到了一个很少的步(由n(4)变为2n(2))

贴上代码

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<cmath>
using namespace std;
int hash1[2000011];
int main(void)
{
	int a, b, c, d;
	while (scanf("%d%d%d%d", &a, &b, &c, &d) != EOF)
	{
		int sum = 0;
		if (a*b > 0 && b*c > 0 && c*d > 0)//简单剪枝,判断abcd是否都是同号
		{
			printf("0\n");
			continue;
		}
		memset(hash1, 0, sizeof(hash1));//每一步不能忘记初始化哈希表
		for (int i = 1;i <= 100;++i)//先计算ab的和,1000000是防止ab的和是负数
		{
			for (int j = 1;j <= 100;++j)
			{
				hash1[a*i*i + b*j*j + 1000000]++;
			}
		}
		for (int i = 1;i <= 100;++i)//计算cd和的相反数,并判断此时改数是否在哈希表中
		{
			for (int j = 1;j <= 100;++j)
			{
				sum += hash1[-c*i*i - d*j*j + 1000000];
			}
		}
		printf("%d\n", sum * 16);//因为x1,x2,x3,x4都有可能是正数或者负数所以有2的4次方种可能性。
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41780519/article/details/80314975