Friends and Berries URAL - 2067 (计算三点共线和计算的时候的注意点)

题目链接:https://cn.vjudge.net/problem/URAL-2067

具体思路:判断三点共线就可以了,只有一对点能满足,如果一对就没有那就没有满足的.

在计算的时候,要注意,如果是按照斜率算的话,可以把除法转换为乘法,防止精度的损失.

如果是按照距离算的话,一定要注意一点,在枚举的时候我们是选择左下和右上的点,然后再去枚举中间的每一个点,一开始我为了防止精度的损失并没有对每段距离进行开根号,直接按照平方的进行计算,但是要注意一点

假设三个点.分别是 ( x1 , y1 )  ( x2 , y2 ) 和 ( x3 , y3 ),比较的时候比较的应该是

sqrt( (x2-x1)^2 + (y2-y1)^2) + sqrt( (x3-x2)^2 + (y3-y1)^2 ) 和 sqrt( (x3-x1)^2 + (y3-y1)^2)之间的大小.

这个和  (x2-x1)^2 + (y2-y1)^2) +  (x3-x2)^2 + (y3-y1)^2 和  (x3-x1)^2 + (y3-y1)^2  之间的大小.  是完全不一样的. 如果将第一项进行平方的话,和第二项会查着一项.

不过对于这个题的话,用距离算的话,肯定会有精度损失,还是用斜率做比较稳妥.

AC代码:

#include<iostream>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<stdio.h>
#include<cmath>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
# define pi acos(-1.0)
const int mod = 1e9 ;
const int maxn = 200000+100;
const int eps = 1e-6;
struct node
{
    ll x,y;
    int id;
} q[maxn];
bool cmp(node t1,node t2)
{
    if(t1.x!=t2.x)return t1.x<t2.x;
    return t1.y<t2.y;
}
ll cal(node t1,node t2)
{
    return (t1.x-t2.x)*(t1.x-t2.x)+(t1.y-t2.y)*(t1.y-t2.y);
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%lld %lld",&q[i].x,&q[i].y);
        q[i].id=i;
    }
        sort(q+1,q+n+1,cmp);
//    for(int i=1;i<=n;i++){
//    cout<<q[i].id<<" "<<q[i].x<<" "<<q[i].y<<endl;
//    }
    int flag=1;
    ll ans=cal(q[1],q[n]);
    //cout<<ans<<endl;
    ll t1=q[1].x-q[n].x;
    ll t2=q[1].y-q[n].y;
    for(int i=2; i<=n-1; i++)
    {
    ll s1=q[1].x-q[i].x;
    ll s2=q[1].y-q[i].y;
    if(s1*t2!=s2*t1){
    flag=0;
    break;
    }
//        if(cal(q[i],q[1])+cal(q[i],q[n])>ans)
//        {
//            flag=0;
//            break;
//        }
    }
    if(flag)
    {
        printf("1\n");
        printf("%d %d\n",q[1].id,q[n].id);
    }
    else
    {
        printf("0\n");
    }
    return 0;
}

 

posted @ 2018-12-12 21:16  Let_Life_Stop  阅读(204)  评论(0编辑  收藏  举报