Tell Your World
题目链接:Tell Your World
题意:给你n个点的坐标,问是否有两条斜率相同但不重合的直线能够覆盖所有的点
思路:直线的斜率肯定为(点1和点2组成)直线1,(点2和点3组成)直线2和(点1和点3组成)直线3这三条直线中的一个
因此可以直接枚举三个斜率判断是否有符合条件的结果即可
代码:
#include<stdio.h>
#include<set>
#include<algorithm>
using namespace std;
int a[1010],n;
set<double>s;
bool judge(double k)
{
s.clear();
for(int i=1; i<=n; ++i)
s.insert(a[i]*1.0-k*i);
return s.size()==2;
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; ++i)
scanf("%d",&a[i]);
if(judge((a[2]-a[1])/1.0)||judge((a[3]-a[2])/1.0)||judge((a[3]-a[1])/2.0))
printf("Yes\n");
else
printf("No\n");
return 0;
}
比赛中写了一下,但是没想那么透。直接寻找是否存在符合条件的两条直线
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
const double eps=1e-8;
int a[1010],b[5];
struct point
{
int x,y;
point() {}
point(int X,int Y)
{
x=X,y=Y;
}
};
void swp(point &s1,point &s2)//交换两点
{
point ss;
ss.x=s1.x,ss.y=s1.y;
s1.x=s2.x,s1.y=s2.y;
s2.x=ss.x,s2.y=ss.y;
}
double ads(double x)//绝对值
{
if(x<0)
x=-x;
return x;
}
int xmult(int x1,int y1,int x2,int y2,int x0,int y0)//计算 cross product(P1-P0)x(P2-P0)
{
return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
}
bool dots_inline(int x1,int y1,int x2,int y2,int x3,int y3)//判三点是否共线
{
return xmult(x1,y1,x2,y2,x3,y3)==0;
}
bool isParallel(point s1,point e1,point s2,point e2)//判断两条直线是否平行
{
if(s1.x>s2.x)
swp(s1,s2);
if(e1.x>e2.x)
swp(e1,e2);
double y1=(s2.y-s1.y)*1.0/(s2.x-s1.x);
double y2=(e2.y-e1.y)*1.0/(e2.x-e1.x);
return ads(y1-y2)<eps;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; ++i)
scanf("%d",&a[i]);
int tot=0;
for(int i=3; i<=n; ++i)//1号点和2号点在一条直线上
{
if(!dots_inline(1,a[1],2,a[2],i,a[i]))//是否在第一条直线上
{
if(tot==2)//是否够两个点,确定第二条直线
{
if(!dots_inline(b[1],a[b[1]],b[2],a[b[2]],i,a[i]))//是否在第二条直线上
{
++tot;
break;
}
}
else
{
b[++tot]=i;
if(tot==2)//够两个点,确定了第二条直线
{
if(!isParallel(point(1,a[1]),point(b[1],a[b[1]]),point(2,a[2]),point(b[2],a[b[2]])))//是否与第一条直线平行
{
++tot;
break;
}
}
}
}
}
if(tot==0)
printf("No\n");
else if(tot<=2)
printf("Yes\n");
else
{
b[1]=2;
tot=1;
for(int i=4; i<=n; ++i)//1号点和3号点在一条直线上
{
if(!dots_inline(1,a[1],3,a[3],i,a[i]))
{
if(tot==2)
{
if(!dots_inline(b[1],a[b[1]],b[2],a[b[2]],i,a[i]))
{
++tot;
break;
}
}
else
{
b[++tot]=i;
if(tot==2)
{
if(!isParallel(point(1,a[1]),point(b[1],a[b[1]]),point(3,a[3]),point(b[2],a[b[2]])))
{
++tot;
break;
}
}
}
}
}
if(tot<=2)
printf("Yes\n");
else
{
b[1]=1;
tot=1;
for(int i=4; i<=n; ++i)//2号点和3号点在一条直线上
{
if(!dots_inline(2,a[2],3,a[3],i,a[i]))
{
if(tot==2)
{
if(!dots_inline(b[1],a[b[1]],b[2],a[b[2]],i,a[i]))
{
++tot;
break;
}
}
else
{
b[++tot]=i;
if(tot==2)
{
if(!isParallel(point(2,a[2]),point(b[1],a[b[1]]),point(3,a[3]),point(b[2],a[b[2]])))
{
++tot;
break;
}
}
}
}
if(tot>2)
break;
}
if(tot<=2)
printf("Yes\n");
else
printf("No\n");
}
}
return 0;
}