对于直线的问题一直没有很好的写法,今天总结下判断直线的问题。
Tell Your World
题意:给出坐标为(i,y[i])的一系列点,问能否找到两条平行且不重合的直线,使得所有点都落在两条直线上,且每条直线上至少有一个点。
思路:对于所要求的斜率我们只需要枚举(1,2),(1,3),(2,3)这几个点就一定会有最总要求的斜率的值。判断在每种情况下,是否能满足要求即可。
#include<bits/stdc++.h>
#define debug(a) cout << #a << " " << a << endl
#define LL long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-6
const int N=1e5+7;
using namespace std;
int y[N],n;
bool ok(int a,int b,int c,int d)
{
return (b-a)*(y[d]-y[c])==(d-c)*(y[b]-y[a]);
}
bool check(int x,int y)
{
vector<int> stk;
for(int i=1;i<=n;i++)
if(!ok(x,y,y,i) && i!=y) stk.push_back(i);
if(stk.size()==0) return 0;
for(int i=1;i<(int)stk.size();i++)
if(!ok(x,y,stk[i-1],stk[i])) return 0;
return 1;
}
int main ()
{
//yyy_3y
//freopen("1.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&y[i]);
if(check(1,2) || check(1,3) || check(2,3)) puts("Yes");
else puts("No");
return 0;
}
Pair Of Lines
题意:给出N个点,看这两个点是否在两条线上。
思路:和上面一题思路一样。
#include<bits/stdc++.h>
#define debug(a) cout << #a << " " << a << endl
#define LL long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-6
const int N=1e5+7;
using namespace std;
LL x[N],y[N],n;
bool ok(int a,int b,int c,int d)
{
return (y[b]-y[a])*(x[d]-x[c])==(y[d]-y[c])*(x[b]-x[a]);
}
bool check(int x,int y)
{
vector<int> stk;
for(int i=1;i<=n;i++){
if(!ok(x,y,y,i))
stk.push_back(i);
}
if(stk.size()<=2) return 1;
x=stk[0],y=stk[1];
for(int i=2;i<(int)stk.size();i++){
if(!ok(x,y,y,stk[i])) return 0;
}
return 1;
}
int main ()
{
//yyy_3y
//freopen("1.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&x[i],&y[i]);
}
if(n<=4 || check(1,2) || check(1,3) || check(2,3)) puts("YES");
else puts("NO");
return 0;
}