#431 Div2 Problem B Tell Your World (鸽巢原理 && 思维)

链接 : http://codeforces.com/contest/849/problem/B

题意 : 给出 n 个在直角坐标系上的点,每个点的横坐标的值对应给出的顺序序数,比如 1 2 4 3 则相当于给出了(1,1)、(2,2)、(3,4)、(4,3)这四个点,现在问你能不能找出两条不重叠的平行直线将所有点都覆盖掉

分析 : 假设存在满足题目条件的两条平行直线,那么肯定有一条是落在了1-2(第一和第二个点间连线)或1-3或者2-3上,我们分别考虑这三条直线以及其他点就能够知道是否满足题意了,比如现在考虑1-2这条直线,将不在这条直线上的所有点都暂存起来,最后判断暂存起来的点是否能够连成一条直线,并且斜率与1-2这条直线一样。用同样的方法考虑1-3以及2-3即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
int n;
struct point { int x, y; };
point arr[maxn], tmp[maxn];
double Slope(point fir, point sec) { ///计算两点间连线斜率
    return (double)((double)sec.y-(double)fir.y) / (double)((double)sec.x-(double)fir.x); 
}
bool Case1()
{
    double k = Slope(arr[1], arr[2]);///1 - 2的情况
    int cnt = 0;///不在 1 - 2这条直线上的点的个数
    for(int i=3; i<=n; i++){
        if(Slope(arr[1], arr[i]) != k){ ///挑出不在 1 - 2 这条直线上的点
            tmp[cnt++] = arr[i];
        }
    } 
    if(!cnt) return false;///如果cnt==0那么也就是所有点都在1 - 2上,不满足题意
    if(cnt == 1) return true;///如果挑出来是一个点的情况,那么1 - 2这条线以及这个点是满足题意的
    double kk = Slope(tmp[0], tmp[1]);///计算斜率
    if(kk != k) return false;///如果与 1 - 2的斜率不一致,不满足题意
    for(int i=2; i<cnt; i++){///一个个点去试
        if(Slope(tmp[0], tmp[i]) != kk)
            return false;
    }
    return true;
}
bool Case2()
{
    double k = Slope(arr[1],arr[3]);
    int cnt = 0;
    for(int i=2; i<=n; i++){
        if(i!=3){
            if(Slope(arr[1], arr[i]) != k){
                tmp[cnt++] = arr[i];
            }
        }
    }
    if(!cnt) return false;
    if(cnt == 1) return true;
    double kk = Slope(tmp[0], tmp[1]);
    if(kk != k)return false;
    for(int i=2; i<cnt; i++){
        if(Slope(tmp[0], tmp[i]) != kk)
            return false;
    }
    return true;
}
bool Case3()
{
    double k = Slope(arr[2], arr[3]);
    int cnt = 0;
    for(int i=1; i<=n; i++){
        if(i!=2 && i!=3){
            if(Slope(arr[2], arr[i]) != k){
                tmp[cnt++] = arr[i];
            }
        }
    }
    if(!cnt) return false;
    if(cnt == 1) return true;
    double kk = Slope(tmp[0], tmp[1]);
    if(kk != k) return false;
    for(int i=2; i<cnt; i++){
        if(Slope(tmp[0], tmp[i]) != kk)
            return false;
    }
    return true;
}
int main(void)
{
    scanf("%d", &n);
    for(int i=1; i<=n; i++){
        arr[i].x = i;
        scanf("%d", &arr[i].y);
    }
    if(Case1() || Case2() || Case3()) puts("Yes");
    else puts("No");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/qwertiLH/p/7466315.html