Language: C++

#include <iostream>
#include <cmath>
#include <vector>
#include <set>
using namespace std;

constexpr double EPS = 1e-4;

struct point {
    double x, y;
    point() {}
    point(double x, double y): x(x), y(y) {}

    point operator + (const point& o) const { return point(x+o.x, y+o.y); }
    point operator - (const point& o) const { return point(x-o.x, y-o.y); }
    point operator * (const double a) const { return point(x*a, y*a); }

    bool operator < (const point& o) const { return x == o.x ? y < o.y : x < o.x; }
    bool operator == (const point& o) const { return fabs(x-o.x) < EPS && fabs(y-o.y) < EPS; }
};

struct line {
    point a, b;
    line() {}
    line(point a, point b): a(a), b(b) {}
};

double fabs(point a) { return sqrt(a.x*a.x + a.y*a.y); }
double dist(point a, point b) { return fabs(a - b); }
double dist(line l) { return dist(l.a, l.b); }
double dot(point a, point b) { return a.x*b.x + a.y*b.y; }
double cross(point a, point b) { return a.x*b.y - a.y*b.x; }

double dist_point_line(point p, line l) {
    if (dot(p - l.a, l.b - l.a) >= 0 && dot(p - l.b, l.a - l.b) >= 0)
        return fabs(cross(p - l.a, l.b - l.a)) / dist(l);

    return min(dist(p, l.a), dist(p, l.b));
}

bool has_intersection(line s, line t) {
    double s1 = cross(s.b - s.a, t.a - s.b) * cross(s.b - s.a, t.b - s.b);
    double s2 = cross(t.b - t.a, s.a - t.a) * cross(t.b - t.a, s.b - t.a);
    if (s1 < 0 && s2 < 0) return true;
    else if (s1 * s2 == 0) {
        double d1 = dist_point_line(s.a, t);
        double d2 = dist_point_line(s.b, t);
        double d3 = dist_point_line(t.a, s);
        double d4 = dist_point_line(t.b, s);
        return min(min(d1, d2), min(d3, d4)) == 0;
    }
    return false;
}

point intersection(line s, line t) {
    double c1 = fabs(cross(t.b - t.a, s.a - t.a));
    double c2 = fabs(cross(t.b - t.a, s.b - t.a));
    return s.a + (s.b - s.a) * (c1 / (c1 + c2));
}

int H, W;
int block[605][605];

vector<line> ls;
vector<point> ps;

int main(void) {
    cin >> H >> W;
    for (int i = 0; i <= H; ++i) fill(block[i], block[i]+W+1, 0);
    for (int i = 0 ; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
            char ch; cin >> ch;
            block[i][j] = (ch == '#') ? 1 : 0;
        }
    }

    for (int i = 0; i <= H; ++i) {
        for (int j = 0; j < W; ++j) {
            if ((i == 0 && block[i][j] == 1) || (i > 0 && (block[i][j] ^ block[i-1][j]))) {
                int lj = j++;
                while (j < W) {
                    if ((i == 0 || block[i-1][j] == block[i-1][lj]) &&
                        block[i][j] == block[i][lj])
                        ;
                    else break;
                    ++j;
                }
                ls.emplace_back(point(i, lj), point(i, j));
                ps.emplace_back(i, lj);
                ps.emplace_back(i, j);
                --j;
            }
        }
    }

    for (int i = 0; i <= W; ++i) {
        for (int j = 0; j < H; ++j) {
            if ((i == 0 && block[j][i] == 1) || (i > 0 && (block[j][i] ^ block[j][i-1]))) {
                int lj = j++;
                while (j < H) {
                    if ((i == 0 || block[j][i-1] == block[lj][i-1]) &&
                        block[j][i] == block[lj][i])
                        ;
                    else break;
                    ++j;
                }
                ls.emplace_back(point(lj, i), point(j, i));
                ps.emplace_back(lj, i);
                ps.emplace_back(j, i);
                --j;
            }
        }
    }

    ps.emplace_back(H, W);
    ps.emplace_back(0, 0);
    sort(begin(ps), end(ps), [](point p, point q) {
        if (p.y == 0 && q.y == 0) return p.x < q.x;
        if (p.y == 0) return false;
        if (q.y == 0) return true;
        double a1 = (H - p.x) / p.y;
        double a2 = (H - q.x) / q.y;
        return a1 == a2 ? p.y < q.y : a1 < a2;
    });

    int ans = 0;

    point left_bottom(H, 0);
    for (int i = 0; i < ps.size()-1; ++i) {
        point p1 = ps[i], p2 = ps[i+1];
        point end1 = left_bottom + (p1 - left_bottom) * 1000;
        point end2 = left_bottom + ((p1+p2)*0.5 - left_bottom) * 1000;

        line tiros[2] = {line(left_bottom, end1), line(left_bottom, end2)};
        for (line tiro : tiros) {
            set<point> cs;
            for (line l : ls) {
                if (has_intersection(tiro, l))
                    cs.insert(intersection(tiro, l));
            }

            ans = max(ans, (int)cs.size()/2 + 1);

        }
    }

    cout << ans << endl;

    return 0;
}



Compiler output:
a.cc: In function 'int main()':
a.cc:117:5: error: 'sort' was not declared in this scope; did you mean 'sqrt'?
  117 |     sort(begin(ps), end(ps), [](point p, point q) {
      |     ^~~~
      |     sqrt