这两题的思路都是将等式化成左右两部分,用一个hash数组,先把左边的结果存起来,然后计算右边的结果直接寻址就行,不过,HDU那道题要注意剪枝,如果系数全为正或者全为负则直接输出0,POJ那道题hash函数定义成char型的,否则会超内存。。
HDU_1496 Equations:
#include#include #include 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#include #include 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; }