我发现了Find the minimum difference between two arrays的帖子 并且使用我试图解决SPOJ问题的概念 - http://www.spoj.pl/problems/ACPC11B但奇怪的是我得到了WA(错误答案)!!!!
然后我尝试了简单的方法..
使用两个for循环..
计算每个元素之间的差异...
然后我得到了AC。 !!!!
任何人都可以告诉我为什么这个方法
if(| A [i + 1] - B [j] |< | A [i] - B [j + 1] |)然后递增i,否则增量j在这种情况下失败????
答案 0 :(得分:2)
第一个链接中的方法仅在两个数组都已排序时才有效。 SPOJ问题涉及未排序的数组。这就是该方法不起作用的原因。如果对数组进行排序,则可以应用第一种方法,但是您需要跟踪原始索引(即排序前每个值的位置)。通过将每个值转换为(值,索引)对然后对这些对进行排序,这是可行的。这样你将有一个O(m log m + n log n)解决方案,而不是你的强力(但正确)O(mn)解决方案(其中m和n是数组长度)。
编辑根据您发布的代码,我有不同的答案。您的循环条件错误。例如,如果i == (x - 1)
只有j != (y - 1)
,则循环将执行,您将a[x]
与b[j]
进行比较。这是a
的非法下标。此外,这应该是读取SPOJ中描述的相同输入吗?我不知道你在哪里读取测试用例的数量。
答案 1 :(得分:0)
您无法比较数组的第一个元素。也就是说,如果最小差异是| a[0]-b[0]
|并且在任何其他元素对之间不会出现这种差异,因为您的比较以| a[1]-b[0]
|开头,所以您将无法找到它和| a[0]-b[1]
|。
答案 2 :(得分:0)
这是我认为应该做的伎俩(基于你的代码),基本上你的代码没有检查2个案例:
首先,当最小值介于数组中的2个第一个值之间时。
其次是我们检查了一个数组中的每个值,但仍然在第二个数组中有值。 (考虑案例a [0,1,2],b [-1,-2,-3,-5,-6,2])
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int comp(const void * a,const void * b)
{
if (*(int*)a==*(int*)b)
return 0;
else if (*(int*)a < *(int*)b)
return -1;
else
return 1;
}
int main()
{
int x,y;
printf("x: ");
scanf ("%d", &x);
int a[x];
srand(time(NULL));
for (int i = 0; i < x; i++)
{
a[i] = rand() % 30 - 15;
//scanf ("%d", &a[i]);
printf ("%d\n",a[i]);
}
printf("y: ");
scanf ("%d", &y);
int b[y];
for (int i = 0; i < y; i++)
{
b[i] = rand() % 30 - 15;
//scanf ("%d", &b[i]);
printf ("%d\n",b[i]);
}
qsort(a,x,sizeof(int),comp) ;
qsort(b,y,sizeof(int),comp) ;
int i = 0, j = 0;
int * inc; // using a pointer to select which var to increment. Avoid repeating code, optional and subjective approach.
int minimum = abs(a[0]-b[0]); // Set min to be a[0] - b[0] which is never checked in the loop
/* Added the min > 0 condition to avoid looping unnecessarily and avoid the break statement
Changed the condition from && to || in order to handle the second case
Changed the != to < which is more restrictive */
while (minimum > 0 && (i < (x - 1) || j < (y - 1)))
{
int z;
if ( i == x-1) // we've reached the end of a, inc j automatically
{
inc = &j;
z = abs(a[i]-b[j+1]);
}
else if ( j == y -1 ) // we've reached the end of b, inc i automatically
{
inc = &i;
z = abs(a[i+1]-b[j]);
}
else // here's the original loop, rewritten to shorten the code
{
int zi = abs(a[i+1]-b[j]);
int zj = abs(a[i]-b[j+1]);
if ( zi < zj)
{
inc = &i;
z = zi;
}
else
{
inc = &j;
z = zj;
}
}
if ( z < minimum)
{
minimum = z;
}
(*inc)++;
}
printf("min: ");
printf ("%d\n", minimum);
return 0;
}