最近参加校招笔试,百度有一个程序题大概意思是有一个小区内分散住着一些住户房屋,小区为了安全想要将所有住户用篱笆围起来,篱笆只能是直线段,并且篱笆可以利用住户的外墙,现给出住户的坐标,求出将所有住户围起来篱笆需要需要穿过多少个住户。
问题可以简化为坐标系上有一系列的点,将最外侧的点连接圈出一个封闭空间,所有其它点都在这个空间内。如输入为二位数组{{1,1},{2,2},{3,3},{4,2},{4,0},{3,-1},{4,-4},{0,-4}},我们通过连接(1,1)、(2,2)、(3,3)、(4,2)、(4,0)、(4,-4)、(0,-4),将所有其他点圈入空间内,连接点总数是7,最后返回值为7,既需要穿过7家住户。
稍微想一下就能发现,所有连线都有一个特点,就是连线外的其他点都在本连线上,或者其它点只在连线的一侧,基于这个条件,找出满足条件的两点确定的直线的条数(此处有一个问题,就是可能多个点在同一条直线上,此处的处理方法就是如果有其它点在这两点之间,则此两点确定的直线不作计数),方法和代码都已验证正确。
这里写代码片 c++
int findfence(int numHouse, int coordinateList[][2])
{
int count=0;
for(int i=0;i<numHouse-1;++i)
{
for(int j=i+1;j<numHouse;++j)
{
bool flag1=false;
bool flag2=false;
bool flag3=false;
double A,B;
if(coordinateList[i][0]==coordinateList[j][0])
{
for(int k=0;k<numHouse;k++)
{
if(coordinateList[k][0]<coordinateList[i][0])
flag1=true;
else if(coordinateList[k][0]>coordinateList[i][0])
flag2=true;
else if(((coordinateList[k][1]-coordinateList[i][1])*(coordinateList[k][1]-coordinateList[j][1]))<0)
flag3=true;
}
if(!(flag1&&flag2))
if(!flag3)
++count;
}
else
{
A=double(coordinateList[i][1]-coordinateList[j][1])/(coordinateList[i][0]-coordinateList[j][0]);
B=double((coordinateList[i][0]*coordinateList[j][1])-(coordinateList[j][0]*coordinateList[i][1]))/(coordinateList[i][0]-coordinateList[j][0]);
for(int k=0;k<numHouse;++k)
{
if(((A*coordinateList[k][0])+B)<coordinateList[k][1])
flag1=true;
else if(((A*coordinateList[k][0])+B)>coordinateList[k][1])
flag2=true;
else if(((coordinateList[k][0]-coordinateList[i][0])*(coordinateList[k][0]-coordinateList[j][0]))<0)
flag3=true;
}
if(!(flag1&&flag2))
if(!flag3)
++count;
}
}
}
return count;
}