# [find rules] srm599 500 point findpolygons

## Description

Find a lattice polygon with the smallest number of sides so that the perimeter is equal to L. if there are multiple solutions, find the one with the shortest difference between the longest side and the shortest side.

## Solution

• All sides are integers.
• There is no solution for L=2.
• L is an odd number without solution:
• For one of the edges, two points (x1,y1) and (x2,y2) are connected.
• c2=(x1−x2)2+(y1−y2)2 .
• If c is odd, one of the parity of x or y will change.
• If c is even, the parity of x and y will change or not change at the same time.
• L is an odd number, which means that there are odd numbers of sides with odd side length, and the polygon starts from a certain point and returns to this point. Finally, the parity of X and y is not the same as that of the original. Conflicts with xn=x0 and yn=y0.
• L ≡ 0(mod4) can form a square with side length of L4
• L ≡ 2(mod4) can form a rectangle with L+24 and l − 24 sides respectively.
• As for whether there is a triangle with an integral point, only the legal points in the first quadrant need to be enumerated.

tc's evaluation machine is really fast~~

```// BEGIN CUT HERE

// END CUT HERE
#line 5 "FindPolygons.cpp"
#include <bits/stdc++.h>
using namespace std;

const int INF = 1 << 30;
const int N = 5050;
typedef pair<int, int> Pairs;

short s[N * N];
int ans;
vector<Pairs> p;

class FindPolygons {

public:

inline int Abs(int x) {
return x < 0 ? -x : x;
}
double minimumPolygon(int L) {
//\$CARETPOSITION\$
if (L & 1) return -1;
if (L == 2) return -1;
for (int i = 1; i <= L; i++)
s[i * i] = i;
p.clear();
for (int i = 0; i <= L / 2; i++)
for (int j = 0; j * j + i * i <= L * L / 4; j++)
if ((i || j) && s[i * i + j * j]) {
p.push_back(Pairs(i, j));
}
ans = INF;
for (int i = 0; i < p.size(); i++) {
Pairs u = p[i]; int v, x = u.first, y = u.second, a, b, c;
a = s[x * x + y * y];
for (int j = i + 1; j < p.size(); j++) {
Pairs v = p[j];
if (u == v) continue;
int xx = v.first, yy = v.second;
b = s[xx * xx + yy * yy];
c = (x - xx) * (x - xx) + (y - yy) * (y - yy);
if (c > L * L) continue; c = s[c];
if (!c) continue; if (a + b + c != L) continue;
if (x * yy == xx * y) continue;
ans = min(ans, max(Abs(a - b), max(Abs(b - c), Abs(c - a))));
}
}
if (ans == INF) ans = (L >> 1) & 1;
return ans;
}

// BEGIN CUT HERE
public:
void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
private:
template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
void verify_case(int Case, const double &Expected, const double &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
void test_case_0() { int Arg0 = 4; double Arg1 = 0.0; verify_case(0, Arg1, minimumPolygon(Arg0)); }
void test_case_1() { int Arg0 = 5; double Arg1 = -1.0; verify_case(1, Arg1, minimumPolygon(Arg0)); }
void test_case_2() { int Arg0 = 12; double Arg1 = 2.0; verify_case(2, Arg1, minimumPolygon(Arg0)); }
void test_case_3() { int Arg0 = 4984; double Arg1 = 819.0; verify_case(3, Arg1, minimumPolygon(Arg0)); }

// END CUT HERE

};

// BEGIN CUT HERE

int main(void) {
FindPolygons ___test;
___test.minimumPolygon(16);
___test.run_test(-1);
system("pause");
}
// END CUT HERE```

Posted on Sun, 31 May 2020 09:02:47 -0400 by Petty_Crim