Friends and Berries URAL - 2067 (計算三點共線和計算的時候的注意點)
阿新 • • 發佈:2018-12-16
題目連結: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; }