Description
有如下方程:
a
1
x
1
3
+
a
2
x
2
3
+
a
3
x
3
3
+
a
4
x
4
3
+
a
5
x
5
3
=
0
a_1x_1^{3}+a_2x_2^{3}+a_3x_3^{3}+a_4x_4^{3}+a_5x_5^{3}=0
a1x13+a2x23+a3x33+a4x43+a5x53=0
系数:
a
1
,
.
.
.
,
a
5
∈
[
−
50
,
50
]
a_1,...,a_5 \in [-50, 50]
a1,...,a5∈[−50,50]
未知数:
x
1
,
.
.
.
,
x
5
∈
[
−
50
,
50
]
,
x
i
=
̸
0
,
a
n
y
i
∈
1
,
2
,
3
,
4
,
5
x_1,...,x_5 \in [-50,50],x_i =\not0,any \ i \in{1,2,3,4,5}
x1,...,x5∈[−50,50],xi≠0,any i∈1,2,3,4,5
求满足方程得解的个数
Input
输入 a1, a2, a3, a4, a5, separated by blanks.
Output
方程解的个数
Sample Input
37 29 41 43 47
Sample Output
654
思路: 每个未知数有100种可能,对每个未知数直接枚举则时间复杂度为O(100^5),在这题会超时。遇到这种指数级复杂度,且底数比较大的可以使用meet in the middle来降低时间复杂度。
meet in the middle的做法是将5个未知数分为两组,第一组为
x
1
,
x
2
x_1,x_2
x1,x2,第二组为
x
3
,
x
4
,
x
5
x_3,x_4,x_5
x3,x4,x5
对第一组未知数的每种可能进行枚举,计算出
s
u
m
1
=
a
1
x
1
3
+
a
2
x
2
3
sum1 = a_1x_1^{3}+a_2x_2^{3}
sum1=a1x13+a2x23,将sum1存入哈希表dic中(哈希表的key为sum1,value为sum1出现的次数),之后枚举第二组未知数,计算
s
u
m
2
=
a
3
x
3
3
+
a
4
x
4
3
+
a
5
x
5
3
sum2 = a_3x_3^{3}+a_4x_4^{3}+a_5x_5^{3}
sum2=a3x33+a4x43+a5x53,在哈希表dic中得到第一组枚举结果为-sum2(sum1+sum2=0移项得到)出现的次数dic[-sum2],此时sum1+sum2=0。记录方程的解的数量ans+=dic[-sum2]。
这题使用STL的map会超时,可以自己构建一个足够大的数组模拟哈希表。
sum1的可能范围为[-12500000, 12500000],我们创建一个哈希表
#define MAX_NUM 25000000
short hsh[MAX_NUM+10];
计算sum1:int sum1 = a1*x1*x1*x1 + a2*x2*x2*x2;
因为我们是用数组下标作为key(sum1),而数组下标不能为负数,所以我们把sum1加上一个数,使得所有的sum1都为正数,并且将该下标数组内的值加一
hsh[sum1 + 12500000]++;//[-12,500,000, 12,500,000]->[0, MAX_NUM]
最后计算出sum2时:int sum2 = a3*x3*x3*x3 + a4*x4*x4*x4 + a5*x5*x5*x5;
我们并不是直接去哈希表里找-sum2的内容,因为此时方程其实可以看成sum1+12500000 + sum2 - 12500000 = 0,移项,将第一组枚举的结果放在方程左边得到:sum1 + 12500000 = 12500000 - sum2。所以我们需要在哈希表里找12500000 - sum2的内容,这样加起来结果就为0了。
if (hsh[-sum2 + 12500000])//hsh[-sum + 12500000]为枚举x1, x2时,sum1等于-(sum2)的次数
res += hsh[-sum2 + 12500000];//如果这个次数不为零加上由x3,x4,x5产生的sum2结果为0,所以将这个次数累加到res
代码:
#include <iostream>
using namespace std;
#define MAX_NUM 25000000
short hsh[MAX_NUM+10];
int main()
{
int a1, a2, a3, a4, a5, res = 0;
cin>>a1>>a2>>a3>>a4>>a5;
for (int x1 = -50; x1 <= 50; x1++)
{
if (x1 == 0) continue;
for (int x2 = -50; x2 <= 50; x2++)
{
if (x2 == 0) continue;
int sum = a1*x1*x1*x1 + a2*x2*x2*x2;//
hsh[sum + 12500000]++;//[-12,500,000, 12,500,000]->[0, MAX_NUM]
}
}
for (int x3 = -50; x3 <= 50; x3++)
{
if (x3 == 0) continue;
for (int x4 = -50; x4 <= 50; x4++)
{
if (x4 == 0) continue;
for (int x5 = -50; x5 <= 50; x5++)
{
if (x5 == 0) continue;
int sum = a3*x3*x3*x3 + a4*x4*x4*x4 + a5*x5*x5*x5;
if (sum < -12500000 || sum > 12500000) continue;
if (hsh[-sum + 12500000])
res += hsh[-sum + 12500000];
}
}
}
cout<<res<<endl;
return 0;
}