我有五个长整数p,q,s,m和x。数组[]由以下公式创建。
Dim This_Year As Integer
Dim Last_Year As Integer
Private Sub Workbook_Open()
This_Year = Year(Date)
Last_Year = This_Year - 1
End Sub
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Intersect(Target, [A:A]) Is Nothing Then Exit Sub
If IsDate(Target) And Year(Target) = This_Year Then
Application.EnableEvents = False
Target.Value = DateSerial(Last_Year, Month(Target), Day(Target))
Application.EnableEvents = True
End If
End Sub
数字的第一个值(数字[0])是s。
在numbers[0] = s;
for(int i=1; i<numbers.Length;i++){
numbers[i] = (p * numbers[i-1] + q) % m;
}
和i < j
或|numbers[j] - numbers[i]| <= x
找到索引j的最有效方法是什么。
例如,在p = 3,q = 7,s = 1,m = 29 en x = 1的情况下,阵列将是:
数字[0] = 1,数字[1] = 10,数字[2] = 8,数字[3] = 2.
在这种情况下,索引j将是3,因为|numbers[j] - numbers[i]| >= m-x
,因为x是1.
我考虑使用诸如计数排序或基数排序的变体之类的东西,但是我无法使用任何东西。
答案 0 :(得分:0)
因为我&lt; j,那么你需要授予这些数字的长度至少为2。
你可以做两个嵌套循环,外部循环从j = 1到数字.Length - 1(将可能的解决方案赋予最小的j)到i = 0到i&lt;学家
然后根据您的规格比较两个位置。如果为true,则返回j。如果它完成两个循环,则没有解决方案。
编辑:代码示例
public int GetSmallestIndex(long[] numbers, long x, long m)
{
if (numbers.Length >= 2)
{
for (int j = 1; j < numbers.Length; j++)
{
for (int i = 0; i < j; i++)
{
long diff = Math.Abs(numbers[j] - numbers[i]);
if (diff <= x || diff >= m - x)
return j;
}
}
}
return -1; //If no solution is found, return -1 as convention
}
答案 1 :(得分:0)
了解某些内容是否更有效的唯一方法是使用StopWatch
中的System.Diagnostics
对其进行基准测试。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
public static void Main()
{
var stopWatch = new Stopwatch();
stopWatch.Start();
const long x = 1;
var numbers = new long[] {3, 7, 1, 29};
var theSmallestIndex = SmallestIndex(x, numbers);
stopWatch.Stop();
Console.WriteLine("Elapsed Time: {0}", stopWatch.Elapsed);
Console.WriteLine("Smallest Index: {0}", theSmallestIndex);
Console.ReadKey();
}
public static long SmallestIndex(long x, long[] numbers)
{
var values = ValuesMinusTheValueOfPreviousIndex(x, numbers.ToList());
var smallest = values.Values.OrderBy(n => n).FirstOrDefault();
var result = values.Where(n => n.Value.Equals(smallest));
return result.FirstOrDefault().Key;
}
public static Dictionary<int, long> ValuesMinusTheValueOfPreviousIndex(long x, List<long> numbers)
{
var results = new Dictionary<int, long>();
foreach (var number in numbers)
{
var index = numbers.IndexOf(number);
var previousNumber = index > 0 ? numbers.ElementAt(index - 1) : 0;
var result = number - previousNumber;
results.Add(index, result);
}
return results;
}
}
}
答案 2 :(得分:0)
编辑:根据您在评论中的要求添加了Math.Abs
long p = 3, q = 7, s = 1, m = 29, x = 1;
long[] numbers = new long[10];
numbers[0] = s;
for (int i = 1; i < numbers.Length; i++)
{
numbers[i] = (p * numbers[i - 1] + q) % m;
}
// Find the smallest index j in numbers, where i < j &&
// (numbers[j] - numbers[i] <= x || numbers[j] - numbers[i] >= m-x)
int smallestIndex = 0;
long comparison;
for (int j = 1; j < numbers.Length; j++)
{
for (int i = 0; i < j; i++)
{
comparison = Math.Abs(numbers[j] - numbers[i]);
if (comparison <= x || comparison >= m - x)
{
smallestIndex = j;
break;
}
}
if (smallestIndex != 0) break;
}
if (smallestIndex == 0)
{
// No result matches the conditions
}
else
{
// j is the smallest index matching the conditions
// Before using Abs, in the example j is 2, because 8 - 10 = -2, lesser than x
// Now using absolute values, In the example j is 3
}