在给定的时间间隔内查找 a,b,c,x,y,z 的所有可能值,使得 a^x+b^y=c^z
本文关键字:x+b 使得 有可能 时间 查找 | 更新日期: 2023-09-27 18:27:53
我想制作 C# 程序,用于在给定间隔内查找正整数 a,b,c,x,y,z 的组合,以便 a^x+b^y=c^z。 变量 a,b,c 必须在区间 [abc_min,abc_max] 中,x,y,z 必须在区间 [xyz_min,xyz_max] 中。我尝试使用六个 for 循环,但它非常慢。有没有更好的代码可以在非常大的时间间隔(例如 [0,100](内短时间内查找所有组合?这是我的代码,但它很慢:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
try
{
int abc_min = 3, abc_max = 10, xyz_min = 3, xyz_max = 20, num = 0;
int a, b, c, x, y, z;
BigInteger p1, p2, p3;
for (a = abc_min; a <= abc_max; a++)
{
for (b = abc_min; b <= abc_max; b++)
{
for (c = abc_min; c <= abc_max; c++)
{
for (x = xyz_min; x <= xyz_max; x++)
{
for (y = xyz_min; y <= xyz_max; y++)
{
for (z = xyz_min; z <= xyz_max; z++)
{
p1 = BigInteger.Pow(a, x);
p2 = BigInteger.Pow(b, y);
p3 = BigInteger.Pow(c, z);
if (p1 + p2 == p3)
{
Console.WriteLine("{0}^{1}+{2}^{3}={4}^{5}'n", a, x, b, y, c, z);
num += 1;
Console.ReadKey();
Console.WriteLine("----------------------------'n");
}
}
}
}
}
}
}
Console.WriteLine("{0} instances found.", num);
}
catch
{
Console.WriteLine("'nError occured.");
}
Console.ReadKey();
}
}
}
您可以最初计算给定间隔内所有a
值的 x
次幂数组:
BigInteger[,] abcPow = new BigInteger[abc_max - abc_min + 1, xyz_max - xyz_min + 1];
for (a = abc_min; a <= abc_max; a++)
for (x = xyz_min; x <= xyz_max; x++)
abcPow[a - abc_min, x - xyz_min] = BigInteger.Pow(a, x);
然后,您无需在每次迭代时计算BigInteger.Pow
:
for (a = abc_min; a <= abc_max; a++)
{
for (b = a; b <= abc_max; b++)
{
for (c = abc_min; c <= abc_max; c++)
{
for (x = xyz_min; x <= xyz_max; x++)
{
p1 = abcPow[a - abc_min, x - xyz_min];
for (y = xyz_min; y <= xyz_max; y++)
{
p2 = abcPow[b - abc_min, y - xyz_min];
for (z = xyz_min; z <= xyz_max; z++)
{
p3 = abcPow[c - abc_min, z - xyz_min];
if (p1 + p2 == p3)
{
Console.WriteLine("{0}^{1}+{2}^{3}={4}^{5}'n", a, x, b, y, c, z);
num++;
Console.ReadKey();
Console.WriteLine("----------------------------'n");
if (a != b)
{
Console.WriteLine("{0}^{1}+{2}^{3}={4}^{5}'n", b, y, a, x, c, z);
num++;
Console.ReadKey();
Console.WriteLine("----------------------------'n");
}
}
else if (p1 + p2 < p3)
{
// No more solutions could be found for the given z
break;
}
}
}
}
}
}
}
请注意,p1 = ...
和p2 = ...
移出了内部循环,因为它们不依赖于内部循环的变量。
编辑
由于a^x + b^y = b^y + a^x
,从a
开始循环是有意义的b
当找到解决方案时,如果a != b
,则输出两个解决方案。
在我的机器上,它以 ~20
倍的速度加快了计算速度。
这里有
一个想法。
首先,定义看起来像这样的类(这都是转述的 C#,可能需要重构(:
class Exponential
{
public int base;
public int power;
}
class ExponentialResult : List<Exponential>
{
private BigInteger result;
public ExponentialResult(BigInteger value)
{
result = value;
}
public BigInteger Result
{
get { return result; }
}
}
public BigIntegerComparer : IComparer
{
public int Compare(BigIntegerComparer x, BigIntegerComparer y)
{
return (int) BigInteger.Subtract(x, y);
}
}
然后,您需要使用如下所示的内容将表单(base^power(的所有值累积到Exponential
对象中
public Dictionary<BigInteger, ExponentialResult> AccumulateRange(int base_min, int base_max, int power_min, int power_max)
{
Dictionary<BigInteger, ExponentialResult> dictionary = new Dictionary<BigInteger, ExponentialResult>();
for (int base = base_min; base <= base_max; ++base)
{
for(int power = power_min; power <= power_max; ++power)
{
Exponential exp = new Exponential();
exp.base = base;
exp.power = power;
BigInteger result = BigInteger.Pow(base, power);
ExponentialResult set;
if (!dictionary.TryGetValue(result, out set))
{
set = new ExponentialResult(result);
dictionary.Add(result, set);
}
set.Add(exp);
}
}
}
从指定的范围内获得整组值后,您将需要对它们进行排序并正确迭代它们,并检查添加和不添加的内容:
public void Calculate(IDictionary<BigInteger, ExponentialResult> dictionary)
{
SortedList<BigInteger, ExponentialResult> list = new SortedList<BigInteger, ExponentialResult>(dictionary, new BigIntegerComparer());
foreach (KeyValuePair<BigInteger, ExponentialResult> kv1 in list)
{
foreach (KeyValuePair<BigInteger, ExponentialResult> kv2 in list)
{
ExponentialResult sum;
if (list.TryGetValue(BigInteger.Add(kv1.Key, kv2.Key), out sum))
{
//we have found one such that a^x + b^y = c^z
}
if (kv1 == kv2)
{
break;
}
}
}
}
然后,在注释所在的if
的内部,累积一组结果,使得存储在ExponentialResult kv1.Value
中的所有对,加上存储在ExponentialResult kv2.Value
中的所有对,导致存储在ExponentialResult sum
中的所有对。