-
(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;
- }