(1,y1) (2,y2)...(n,yn) 问你这些点能不能被两条平行的直线贯穿,即所有点都在这两条直线上,且这两条直线不能平行
思路:对于大问题,先缩小为小问题
首先,只有两个点的时候,随意都可以把它画成两条平行的线,然后是三个点,那么其中一条线要穿过两个点,然后第三个点所在的直线也必须与前一条直线平行,那么我们就可以找出三种方案,就是两两点组合确定好一条直线。
在画了三个点的情况之后,增加一个点,但是我们只能判断这个点是否在前面的两条直线上,也就是说,前面的三个点就已经确定了线的斜率。
也就是说,利用前面三个点得到的三个斜率,必定有一个是正确的,那么我们就只需要枚举那三个斜率,然后判断是否所有点分布在两条为该斜率且不平行的线上就可以了
我枚举斜率之后,对于每个点,计算出过改点且为该斜率情况下的直线经过Y轴的点的纵坐标是多少,然后记录一下又多少个不同的过Y轴纵坐标,只有当数目为2的时候才正确。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
map<double,int>m;
int op[1005];
double ang[5];
int main(){
int n,y,flag;
double a1,a2,a3;
while(scanf("%d",&n) != EOF){
for(int i = 1;i <= n;i++){
scanf("%d",&op[i]);
}
ang[1] = (op[2] - op[1]) * 1.0 / (2 - 1);
ang[2] = (op[3] - op[2]) * 1.0 / (3 - 2);
ang[3] = (op[3] - op[1]) * 1.0 / (3 - 1);
flag = 0;
for(int a = 1;a <= 3;a++){
int cnt = 0;
m.clear();
for(int i = 1;i <= n;i++){
double b = op[i] - ang[a] * i;
if(!m.count(b)){
m[b] = 1;
cnt++;
}else{
m[b]++;
}
}
if(cnt == 2){
flag = 1;
break;
}
}
if(flag)
puts("Yes");
else
puts("No");
}
return 0;
}