POJ 1840 Eqs(乱搞)题解
思路:这题好像以前有类似的讲过,我们把等式移一下,变成 -(a1*x1^3 + a2*x2^3)== a3*x3^3 + a4*x4^3 + a5*x5^3,那么我们只要先预处理求出左边的答案,然后再找右边是否也能得到就行了,暴力的复杂度从O(n^5)降为O(n^3 + n^2)。因为左式范围-12500000~12500000,所以至少开12500000 * 2的空间,用int会爆,这里用short。如果小于0要加25000000,这样不会有重复的答案,算是简单的hash?
代码:
#include<map> #include<ctime> #include<cmath> #include<cstdio> #include<iostream> #include<algorithm> #define ll long long #define ull unsigned long long using namespace std; const int maxn = 100000 + 10; const int seed = 131; const int MOD = 100013; const int INF = 0x3f3f3f3f; short num[12500000 * 2 + 10]; int main(){ int base = 12500000 * 2; int a1, a2, a3, a4, a5; while(~scanf("%d%d%d%d%d", &a1, &a2, &a3, &a4, &a5)){ memset(num, 0, sizeof(num)); for(int i = -50; i <= 50; i++){ if(!i) continue; for(int j = -50; j <= 50; j++){ if(!j) continue; int sum = -(a1 * i * i * i + a2 * j * j * j); if(sum < 0) sum += base; num[sum]++; } } int ans = 0; for(int i = -50; i <= 50; i++){ if(!i) continue; for(int j = -50; j <= 50; j++){ if(!j) continue; for(int k = -50; k <= 50; k++){ if(!k) continue; int sum = a3 * i * i * i + a4 * j * j * j + a5 * k * k * k; if(sum < 0) sum += base; ans += num[sum]; } } } printf("%d\n",ans); } return 0; }