This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/* TASK: Tiles (tiles)
* Task proposal by: Mikkel Abrahamsen (DNK)
* Task prepared by: Mikkel Abrahamsen (DNK), Dovydas Vadišius (LTU SC), Daumilas Ardickas (LTU SC)
*/
#include <bits/stdc++.h>
using namespace std;
int max_line(int N, int M, std::vector<int> X, std::vector<int> Y)
{
X.push_back(X[0]);
X.push_back(X[1]);
Y.push_back(Y[0]);
Y.push_back(Y[1]);
map<int, set<int>> points; //sets of y coordinates sorted by x coordinates
for (int i = 1; i <= N; i++)
{
//only interesting points are when direction changes
if ((X[i - 1] != X[i] && X[i] == X[i + 1]) || (X[i - 1] == X[i] && X[i] != X[i + 1]))
{
points[X[i]].insert(Y[i]);
}
}
int best = 0; //z
int even_count = 0;
int odd_count = 0;
map<int, int> current; //intervals y coordinates mapped to interval type above it: -1 - empty, 0 - even, 1 - odd interval
for (auto &line : points) //sweep from left to right
{
int x = line.first;
if (even_count == 0)
{
best = max(best, (x - 1) | 1);
}
if (odd_count == 0)
{
best = max(best, x & ~1);
}
int shift = -1; //start of previous interval if it has odd size
auto l = line.second.begin();
while (l != line.second.end()) //check each vertical edge from bottom to top
{
int y1 = *l++;
int y2 = *l++;
auto it = current.upper_bound(y1);
if (it != current.end() && it->first < y2) //edge is contained in more than one interval
return best;
if (it == current.begin() || prev(it)->second == -1) //interior of P is to the right of the edge
{
if (shift >= 0)
{
if (prev(prev(it))->first != shift) //not continuing odd length interval
return best;
}
if (it == current.begin() || prev(it)->first != y1 || prev(prev(it))->second != x % 2) //start new interval
{
current[y1] = x % 2;
(x % 2 ? odd_count : even_count)++;
}
else //merge with previous interval
{
current.erase(prev(it));
}
if ((y1 % 2 == y2 % 2) ^ (shift >= 0)) //if together with previous interval have even size
{
if (it == current.end() || it->first > y2) //close interval
{
current[y2] = -1;
}
else if (it->second == x % 2) //merge with next interval
{
current.erase(it);
(x % 2 ? odd_count : even_count)--;
}
shift = -1;
}
else
{
if (it == current.end() || it->first != y2 || it->second != x % 2) //have odd length interval
return best;
//merge with next interval
current.erase(it);
(x % 2 ? odd_count : even_count)--;
shift = y1;
}
}
else //interior of P is to the left of the edge
{
if (shift >= 0)
{
if (prev(it)->first != shift || y1 % 2 != shift % 2) //have odd length interval
return best;
}
else if (prev(it)->second != x % 2 || prev(it)->first % 2 != y1 % 2) //have odd length interval
{
return best;
}
if (prev(it)->first == y1) //edge's bottom coincides with an interval's end
{
if (prev(it) != current.begin() && prev(prev(it))->second != -1) //previous interval is empty
{
current[y1] = -1;
}
else
{
current.erase(prev(it));
}
(x % 2 ? odd_count : even_count)--;
}
else
{
current[y1] = -1;
}
if (it->first % 2 == y2 % 2) //next interval has even length
{
if (it->first != y2) //edge's top is not on interval's end
{
current[y2] = x % 2;
(x % 2 ? odd_count : even_count)++;
}
else if (it->second == -1) //next interval is empty
{
current.erase(it);
}
shift = -1;
}
else
{
current[y2] = x % 2;
(x % 2 ? odd_count : even_count)++;
shift = y2;
}
}
}
if (shift >= 0)
return best;
}
return best;
}
int main() {
int N, M, x, y, k;
vector<int> X, Y;
cin >> N >> M;
for (int i = 0; i < N; i++) {
cin >> x >> y;
X.push_back(x);
Y.push_back(y);
}
k = max_line(N, M, X, Y);
cout << k << endl;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |