找不到逻辑错误,需要第二双眼睛
Can't find logic error, and need a second pair of eyes
嗨,我正在处理这个acm问题,我似乎不明白为什么我的算法不起作用。
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&项目ID=8&page=show_problem&问题=482
我的sillySort函数应该是找到所有不同的子数组,然后最小化交换值的总和。
我的输出与他们的输出非常接近,但我不确定出了什么问题。我坐下来,甚至把问题写在白板上。有人能发现吗?
#include <iostream>
void swap(int* array, int index1, int index2)
{
int temp;
temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
void printArray(int* array, int size)
{
for(int i = 0; i < size; i++)
{
std::cout << array[i] << " ";
}
std::cout << "n";
}
int sillySort(int* array, int size)
{
int minSum = 0;
bool firstSwap = true;
printArray(array, size);
for(int i = 0; i < size; i++)
{
for(int i2 = i + 1; i2 < size; i2++)
{
//Found a swappable pair
if(array[i] > array[i2])
{
int sum = array[i] + array[i2];
std::cout << "Swapping: " << array[i] << " and " << array[i2] << " (" << sum << ")" << std::endl;
//Temporary swap the array to call silly on it
swap(array, i, i2);
//Calculate silly on new array
int minSilly = sillySort(array, size);
//Found a new minimum
if((minSilly + sum) < minSum || firstSwap)
{
firstSwap = false;
minSum = minSilly + sum;
}
//Move array back into position
swap(array, i, i2);
}
}
}
std::cout << "Returning: " << minSum << std::endl;
return minSum;
}
int main()
{
const int arraySize = 6;
int array[arraySize];
array[0] = 8;
array[1] = 4;
array[2] = 5;
array[3] = 3;
array[4] = 2;
array[5] = 7;
std::cout << sillySort(array, arraySize) << std::endl;
return 0;
}
这是一个有趣的问题!
考虑第二个示例情况:4元素数组为8124。(4元素数组比7元素数组更容易求解;您的程序也没有得到最好的答案。)
最佳成本的正确答案是17。以下是一系列动作(我相信这是独一无二的,但还没有证明),它将为您提供一个成本为17的排序列表。
Swap 1 and 2. Cost is 3. New sequence is 8214.
Swap 1 and 4. Cost is 5. New sequence is 8241.
Swap 1 and 8. Cost is 9. New sequence is 1248 (sorted).
总成本为17。
您的程序无法到达那里,因为它只在元素顺序错误时交换元素。我的第一次交换将1移动到2之后,这将它们从正确的顺序更改为错误的顺序。。。但这一举措正在朝着正确、成本最低的解决方案迈进。
因此,解决方案是放松这样一种假设,即您必须只交换无序的东西。(您还需要重新构造您的算法,因为该假设是目前唯一能阻止无限递归的假设。)