1. 程式人生 > >Friends and Berries URAL - 2067 (計算三點共線和計算的時候的注意點)

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