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