这两题的思路都是将等式化成左右两部分,用一个hash数组,先把左边的结果存起来,然后计算右边的结果直接寻址就行,不过,HDU那道题要注意剪枝,如果系数全为正或者全为负则直接输出0,POJ那道题hash函数定义成char型的,否则会超内存。。
HDU_1496 Equations:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 2000009;
int hash[N];
int main()
{
//freopen("data.in", "r", stdin);
int a, b, c, d, i, j;
while(scanf("%d%d%d%d", &a, &b, &c, &d) != EOF)
{
if((a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0))
{ printf("0\n"); continue;}
memset(hash, 0, sizeof(hash));
for(i = 1; i <= 100; i++)
for(j = 1; j <= 100; j++)
hash[1000000 + a*i*i + b*j*j]++;
int sum = 0;
for(i = 1 ; i <= 100; i++)
for(j = 1; j <= 100; j++)
if(hash[1000000 - c*i*i - d*j*j])
sum += hash[1000000 - c*i*i - d*j*j];
printf("%d\n", sum*16);
}
return 0;
}
POJ_1840 Eqs:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 25000007;
char hash[N]; //!!!
int main()
{
//freopen("data.in", "r", stdin);
int a, b, c, d, e, i, j, k;
while(scanf("%d%d%d%d%d", &a, &b, &c, &d, &e) != EOF)
{
memset(hash, 0, sizeof(hash));
for(i = -50; i <= 50; i++)
{
if(i == 0) continue;
for(j = -50; j <= 50; j++)
{
if(j == 0) continue;
hash[12500000 + a*i*i*i + b*j*j*j]++;
}
}
int sum = 0;
for(i = -50; i <= 50; i++)
{
if(i == 0) continue;
for(j = -50; j <= 50; j++)
{
if(j == 0) continue;
for(k = -50; k <= 50; k++)
{
if(k == 0 || 12500000 < c*i*i*i + d*j*j*j + e*k*k*k || -12500000 > c*i*i*i + d*j*j*j + e*k*k*k) continue;
sum += hash[12500000-c*i*i*i-d*j*j*j-e*k*k*k];
}
}
}
printf("%d\n", sum);
}
return 0;
}