Расстановка точек на прямые

Дано N, точек с заданными координатами, можно ли провести не более двух прямых так, чтобы все точки лежали хотя бы на одной из двух прямых?

Пример 1

Ввод:

6
0 1
1 1
2 1
0 2
1 3
2 2

Вывод:

no

Пример 2

Ввод:

6
2 2
4 6
1 0
2 1
6 1
1 1

Вывод:

yes

Вот мой код:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct line {
    int k, b;
    bool x = false;
};

bool Is3PointsOnLine(pair<float, float> p1, pair<float, float> p2, pair<float, float> p3) {
    if ((p2.first - p1.first) != 0 && (p2.second - p1.second) != 0) {
        return ((p3.first - p1.first) / (p2.first - p1.first) == (p3.second - p1.second) / (p2.second - p1.second));
    }
    else {
        //прямая вида x = a
        if ((p2.first == p1.first && p2.second == p1.second) || (p2.first == p1.first && p2.first == p3.first) || (p2.second == p1.second && p2.second == p3.second))
            return true; //fix me
        else
            return false;
    }
}

bool Is4PointsOnLine(pair<int, int> p1, pair<int, int> p2, pair<int, int> p3, pair<int, int> p4) {
    if (Is3PointsOnLine(p2, p3, p4) && Is3PointsOnLine(p1, p3, p4) &&
        Is3PointsOnLine(p1, p2, p4) && Is3PointsOnLine(p1, p2, p3)) {
        return true;
    }
    return false;
}

pair<bool, int> Is3of4PointsOnLine(pair<int, int> p1, pair<int, int> p2, pair<int, int> p3, pair<int, int> p4) {
    pair<bool, int> ans;
    if (Is3PointsOnLine(p2, p3, p4)) {;
        ans.first = true;
        ans.second = 0;
        return ans;
    } 
    if (Is3PointsOnLine(p1, p3, p4)) {
        ans.first = true;
        ans.second = 1;
        return ans;
    }
    
    if (Is3PointsOnLine(p1, p2, p4)) {
        ans.first = true;
        ans.second = 2;
        return ans;
    }
    if (Is3PointsOnLine(p1, p2, p3)) {
        ans.first = true;
        ans.second = 3;
        return ans;
    }
    ans.first = false;
    return ans;
}

//лежит ли точка на прямой
bool PointIsOnLine(line l, int x, int y) {
    if (!l.x) {
        if (y == ((l.k * x) + l.b))
            return true;
    }
    else {
        if (x == l.b)
            return true;
    }
    return false;
}

/*bool CheckPoint(pair<int, int> p) {
    bool smt = false;
    for (int e = 0; e < lines.size(); e++) {
        if (PointIsOnLine({ lines[e].k, lines[e].b }, p.first, p.second)) {
            lines[e].count++;
            smt = true;
        }
    }

    return smt;
}*/

//составляем уравнение прямой
line f(pair<int, int> c1, pair<int, int> c2) {
    int x1 = c1.first;
    int y1 = c1.second;
    int x2 = c2.first;
    int y2 = c2.second;

    line ans;
    if (x2 != x1) {
        ans.k = (y2 - y1) / (x2 - x1);//fix
        ans.b = -(x1 * y2 - x1 * y1 - x2 * y1 + x1 * y1) / (x2 - x1);
        ans.x = false;
    }
    else {
        ans.k = 0;      
        ans.b = x1;
        ans.x = true;
    }

    return ans;
}

int main() {
    int n;
    cin >> n;
    vector<pair<int, int>> p(n);

    vector<int> not_used;

    for (int i = 0; i < n; i++)
        cin >> p[i].first >> p[i].second;
    
    if (n < 5) {
        cout << "yes";
        cout << "adsdas";
        return 0;
    }
    else {
        vector<line> lines;

        pair<bool, int> needs = Is3of4PointsOnLine(p[0], p[1], p[2], p[3]);

        if (Is4PointsOnLine(p[0], p[1], p[2], p[3])) {
            lines.push_back(f(p[0], p[1]));

            pair<int, int> e = {-8, -8};
            //тут мы подбираем вторую линию
            for (int i = 4; i < n; i++) {
                if (!PointIsOnLine(lines[0], p[i].first, p[i].second)) {
                    if (e.first == -8) {
                        e.first = i;
                    }
                    else if (e.second == -8) {
                        e.second = i;

                        lines.push_back(f(p[e.first], p[e.second]));
                    }
                    else if (!PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                        cout << "no";
                        return 0;
                    }
                }
            }

            if (lines.size() == 2) {
                cout << "yes";
            }
            else {
                cout << "no";
            }
            
            return 0;
        }
        else if (needs.first) {
            pair<int, int> e = { needs.second, -8 };
            vector<int> d = { 0,1,2,3 };
            d.erase(d.begin() + needs.second);
            lines.push_back(f(p[d[0]], p[d[1]]));

            //тут мы подбираем вторую линию
            for (int i = 4; i < n; i++) {
                if (e.second == -8) {
                    if (!PointIsOnLine(lines[0], p[i].first, p[i].second)) {
                        if (e.second == -8) {
                            e.second = i;
                            lines.push_back(f(p[e.first], p[e.second]));
                        }                       
                    }
                }
                else if (!PointIsOnLine(lines[0], p[i].first, p[i].second) && !PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                    cout << "no";
                    return 0;
                }
            }

            cout << "yes";
            return 0;
        }
        else {
            //01 23
            lines = {};
            lines.push_back(f(p[0], p[1]));
            lines.push_back(f(p[2], p[3]));

            bool asdfasdf = false;
            for (int i = 4; i < n; i++) {
                if (!PointIsOnLine(lines[0], p[i].first, p[i].second) && !PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                    asdfasdf = true;
                    break;
                }
            }
            if (!asdfasdf) {
                cout << "yes";
                return 0;
            }


            //02 13
            lines = {};
            lines.push_back(f(p[0], p[2]));
            lines.push_back(f(p[1], p[3]));

            asdfasdf = false;
            for (int i = 4; i < n; i++) {
                if (!PointIsOnLine(lines[0], p[i].first, p[i].second) && !PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                    asdfasdf = true;
                    break;
                }
            }
            if (!asdfasdf) {
                cout << "yes";
                return 0;
            }

            //03 12
            lines = {};
            lines.push_back(f(p[0], p[3]));
            lines.push_back(f(p[1], p[2]));


            asdfasdf = false;
            for (int i = 4; i < n; i++) {
                if (!PointIsOnLine(lines[0], p[i].first, p[i].second) && !PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                    asdfasdf = true;
                    break;
                }
            }
            if (!asdfasdf) {
                cout << "yes";
                return 0;
            }

            cout << "no";
        }
        
    }

    return 0;
}

Но он выдает ошибку на 7-ом тесте, входные данные мне неизвестны. Помогите пожалуйста исправить ошибку

Я попытался сделать с тремя точками, вот код:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct line {
    int k, b;
    bool x = false;
    long long c = 0;
};
//лежит ли точка на прямой
bool PointIsOnLine(line l, int x, int y) {
    if (!l.x) {
        if (y == ((l.k * x) + l.b))
            return true;
    }
    else {
        if (x == l.b)
            return true;
    }
    return false;
}
//составляем уравнение прямой
line f(pair<int, int> c1, pair<int, int> c2) {
    int x1 = c1.first;
    int y1 = c1.second;
    int x2 = c2.first;
    int y2 = c2.second;
    line ans;
    if (x2 != x1) {
        ans.k = (y2 - y1) / (x2 - x1);//fix
        ans.b = -(x1 * y2 - x1 * y1 - x2 * y1 + x1 * y1) / (x2 - x1);
        ans.x = false;
        ans.c = 2;
    }
    else {
        ans.k = 0;      
        ans.b = x1;
        ans.x = true;
        ans.c = 2;
    }
    return ans;
}
int main() {
    int n;
    cin >> n;
    vector<pair<int, int>> p(n);
    vector<int> not_used;
    for (int i = 0; i < n; i++)
        cin >> p[i].first >> p[i].second;
    
    if (n < 5) {
        cout << "yes";
        return 0;
    }
    else {
        //
        vector<line> lines;
        lines.push_back(f(p[0], p[1]));
        pair<int, int> e = { -8, -8 };
        for (int i = 2; i < n; i++) {
            if (PointIsOnLine(lines[0], p[i].first, p[i].second)) {
                lines[0].c++;
            }
            else if (e.first == -8) {
                e.first = i;
            }
            else if (e.second == -8) {
                e.second = i;
                lines.push_back(f(p[e.first], p[e.second]));
            }
            else if (PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                lines[1].c++;
            }
            else if (!PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                break;
            }
        }
        if (lines[0].c + lines[1].c == n) {
            cout << "yes";
            return 0;
        }
        lines = {};
        lines.push_back(f(p[0], p[2]));
        lines.push_back(f(p[1], p[2]));
        for (int i = 3; i < n; i++) {
            if (PointIsOnLine(lines[0], p[i].first, p[i].second)) {
                lines[0].c++;
            }
            else if (PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                lines[0].c++;
            }
            else if (!PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                cout << "no";
                return 0;
            }
        }
        if (lines[0].c + lines[1].c == n)
            cout << "yes";
    }
    return 0;
}

Но ведь вариант с тремя точками не будет работать, если все точки будут расположены на двух параллельных прямых

Попробовал еще раз переделать, теперь валится на 5-ом тесте:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct line {
    int k, b;
    bool x = false;
    long long c = 0;
};

//лежит ли точка на прямой
bool PointIsOnLine(line l, int x, int y) {
    if (!l.x) {
        if (y == ((l.k * x) + l.b))
            return true;
    }
    else {
        if (x == l.b)
            return true;
    }
    return false;
}

//составляем уравнение прямой
line f(pair<int, int> c1, pair<int, int> c2) {
    int x1 = c1.first;
    int y1 = c1.second;
    int x2 = c2.first;
    int y2 = c2.second;

    line ans;
    if (x2 != x1) {
        ans.k = (y2 - y1) / (x2 - x1);//fix
        ans.b = -(x1 * y2 - x1 * y1 - x2 * y1 + x1 * y1) / (x2 - x1);
        ans.x = false;
        ans.c = 0;
    }
    else {
        ans.k = 0;      
        ans.b = x1;
        ans.x = true;
        ans.c = 0;
    }

    return ans;
}

int main() {
    int n;
    cin >> n;
    vector<pair<int, int>> p(n);

    vector<int> not_used;

    for (int i = 0; i < n; i++)
        cin >> p[i].first >> p[i].second;
    
    if (n < 5) {
        cout << "yes";
        return 0;
    }
    else {
        //
        vector<line> lines;

        for (int p1 = 0; p1 <= 2; p1++) {
            for (int p2 = 0; p2 <= 2; p2++) {
                if (p2 != p1) {
                    for (int p3 = 0; p3 < 4; p3++) {
                        if ((p3 != p1) && (p3 != p2)) {
                            for (int p4 = 0; p4 < 4; p4++) {
                                if ((p4 != p1) && (p4 != p2) && (p4 != p3)) {
                                    //cout << p1 << p2 << p3 << p4 << "\n";

                                    vector<int> not_used;
                                    pair<int, int> e = { -8, -8 };

                                    //строим прямые
                                    lines = {};
                                    lines.push_back(f(p[p1], p[p2]));
                                    lines.push_back(f(p[p3], p[p4]));

                                    for (int i = 0; i < n; i++) {
                                        if (PointIsOnLine(lines[0], p[i].first, p[i].second)) {
                                            lines[0].c++;
                                        }
                                        else if (PointIsOnLine(lines[1], p[i].first, p[i].second)) {
                                            lines[1].c++;
                                        }
                                        else if (e.first == -8) {
                                            e.first = i;
                                        }
                                        else if (e.second == -8) {
                                            e.second = i;
                                            lines.push_back(f(p[e.first], p[e.second]));
                                            lines[2].c = 2;

                                            for (int j = 0; j <= 3; j++) {
                                                if (PointIsOnLine(lines[2], p[j].first, p[j].second)) {
                                                    lines[2].c++;
                                                }
                                            }
                                        }
                                        else if (PointIsOnLine(lines[2], p[i].first, p[i].second)) {
                                            lines[1].c++;
                                        }
                                        else {
                                            not_used.push_back(i);
                                        }
                                    }

                                    if (e.first != -8 && e.second == -8) {
                                        not_used.push_back(e.first);
                                    }

                                    if (not_used.size() > 0) {
                                        if (not_used.size() >= 2) {
                                            lines.push_back(f(p[not_used[0]], p[not_used[1]]));
                                            for (int j = 0; j < not_used.size(); j++) {
                                                if (PointIsOnLine(lines[lines.size()-1], p[not_used[j]].first, p[not_used[j]].second)) {
                                                    lines[lines.size()-1].c++;
                                                }
                                            }
                                        }
                                        else {
                                            for (int i = 0; i <= 3; i++) {
                                                lines.push_back(f(p[not_used[0]], p[i]));
                                                lines[lines.size() - 1].c = 1;
                                                for (int j = 0; j <= 3; j++) {
                                                    if (PointIsOnLine(lines[lines.size()-1], p[j].first, p[j].second)) {
                                                        lines[lines.size()-1].c++;
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    for (int counter1 = 0; counter1 < lines.size(); counter1++) {
                                        for (int counter2 = 0; counter2 < lines.size(); counter2++) {
                                            if (counter1 != counter2 && lines[counter1].c + lines[counter2].c >= n) {
                                                cout << "yes";
                                                return 0;
                                            }
                                        }
                                    }
                
                                }
                            }
                        }
                    }
                }
            }
        }

        cout << "no";
    }

    

    return 0;
}

Ответы (0 шт):