B. Tell Your World
Source
http://codeforces.com/contest/849/problem/B
Connect the countless points with lines, till we reach the faraway yonder.
There are n points on a coordinate plane, the i-th of which being (i, yi).
Determine whether it's possible to draw two parallel and non-overlapping lines, such that every point in the set lies on exactly one of them, and each of them passes through at least one point in the set.
The first line of input contains a positive integer n (3 ≤ n ≤ 1 000) — the number of points.
The second line contains n space-separated integers y1, y2, ..., yn ( - 109 ≤ yi ≤ 109) — the vertical coordinates of each point.
Output "Yes" (without quotes) if it's possible to fulfill the requirements, and "No" otherwise.
You can print each letter in any case (upper or lower).
5
7 5 8 6 9
Yes
5
-1 -2 0 0 -5
No
5
5 4 3 2 1
No
5
1000000000 0 0 0 0
Yes
In the first example, there are five points: (1, 7), (2, 5), (3, 8), (4, 6) and (5, 9). It's possible to draw a line that passes through points 1, 3, 5, and another one that passes through points 2, 4 and is parallel to the first one.
In the second example, while it's possible to draw two lines that cover all points, they cannot be made parallel.
In the third example, it's impossible to satisfy both requirements at the same time.
Solution
题意:给一堆点(i, yi),问你能否找出两条平行的直线,使得每个点都被其中一条直线穿过,而且每条直线至少要穿过一个点。
暴力判断。
始终把(1, y1)视为第一条直线需要穿过的第一个点,然后枚举第一条直线需要穿过的第二个点,这样就确定了斜率,接着就可以把剩下的也在这条直线上的点都给找出来,然后就只剩下不在这条直线上的,判断一下他们是否共线,并且构成的直线斜率跟第一条直线相同。注意还需要处理一下第一条直线只穿过一个点的情况和所有点都共线的情况。
为了避免精度误差,不要把斜率算出来。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 int n; 6 ll y[1011]; 7 vector<int> vec; 8 9 int main(){ 10 ios::sync_with_stdio(false); 11 cin >> n; 12 for(int i = 1;i <= n;++i) cin >> y[i]; 13 14 if((y[2]-y[1])*(3-1) != (y[3]-y[1])*(2-1)){ 15 for(int j = 4;j <= n;++j) 16 if((y[3]-y[2])*(j-2) != (y[j]-y[2])*(3-2)) goto HELL; 17 cout << "Yes"; 18 return 0; 19 HELL:; 20 } 21 22 for(int i = 2;i <= n;++i){ 23 vec.clear(); 24 for(int j = 2;j < i;++j) vec.push_back(j); 25 for(int j = i + 1;j <= n;++j) 26 if((y[i]-y[1])*(j-1) != (y[j]-y[1])*(i-1)) vec.push_back(j); 27 if(vec.empty()) break; 28 if((int)vec.size() >= 2 && (y[i]-y[1])*(vec[1]-vec[0]) != (y[vec[1]]-y[vec[0]])*(i-1)) goto hell; 29 for(int j = 2;j < vec.size();++j) 30 if((y[vec[1]]-y[vec[0]])*(vec[j]-vec[0]) != (y[vec[j]]-y[vec[0]])*(vec[1]-vec[0])) goto hell; 31 cout << "Yes"; 32 return 0; 33 hell:; 34 } 35 36 cout << "No"; 37 38 return 0; 39 }