说我的起点是x-y平面上的原点。
我只允许以某种方式移动。 有人告诉我,我的下一步行动只能是2个坐标点的线性组合。
我的目标是,在尽可能多的动作中找出最接近我可以到达的起点的点(当然除了原点)。
例如,如果我被告知2点是a =(13,4)和b =(17,5)。
因此,我可以从原点得到的最接近的是(1,1)。这是从4a-3b获得的。
我为它编写了一个程序。但据我所知,逻辑是完全有缺陷的。
然而,它为我尝试过的少数测试用例输出了正确的答案。
这是我的代码
#include<math.h>
int sq(int a)
{
return a*a;
}
int main(void)
{
int a,b,c,d,min=200000,i,j,n=100;
scanf("%d %d %d %d",&a,&b,&c,&d);
for(i=-100;i<n;i++)
{
for(j=-100;j<n;j++)
{
if(sq((i*a)-(j*c))+sq((i*b)-(j*d))<min)
{
min=sqrt(sq((i*a)-(j*c)))+sqrt(sq((i*b)-(j*d)));
}
}
}
printf("%d\n",min);
return(0);
}
随意提供您的意见,以及是否有更好的方法来解决问题。
程序中输出的答案是| x | + | y |。
答案 0 :(得分:2)
如果你进行数学计算,你会发现有一种更简单的方法可以进行详尽的搜索。
设 l,m 为线性组合的系数(在您的示例中 l = 4 和 m = -3 )。另外,让 a =(x1,y1)和 b =(x2,y2)。
然后很容易证明您需要找到 a,b ,这样可以最大限度地减少f(l,m) = slm
s = sign(x1*x2 + y1*y2)
所在的函数。
此外,如果您可以访问非线性求解器(或者您可以编写自己的算法,因为这是一个简单的函数),您可以迭代地找到解决方案。
答案 1 :(得分:1)
我没有尝试详细分析您的代码,但是我突然想到的是min
赋值中的表达式与前面if
中的表达式不同:
if(sq((i*a)-(j*c))+sq((i*b)-(j*d))<min)
{
min=sqrt(sq((i*a)-(j*c)))+sqrt(sq((i*b)-(j*d)));
我很确定这两者应该是相同的(可能甚至计算一次并存储在变量中)。
此外,将sqrt()
的(浮点)结果赋值给整数变量看起来很可疑。使用距离的 square 可能是有意义的,并且完全避免sqrt()
。
最后,您只考虑线性组合,其中第一个系数为正,第二个系数为负。您应该考虑其他可能性,包括其中一个系数为零的那些。