[找规律] SRM599 500-point FindPolygons

来源:互联网 发布:mac os sierra升级 编辑:程序博客网 时间:2024/06/06 23:50

Description

找到一个边数最小的格点多边形使得周长等于L,若有多解,要找到最长边和最短边相差最短的。

Solution

  • 所有边为整数。
  • L=2无解。
  • L为奇数无解:
    • 对于其中的一条边连接了两个点(x1,y1)(x2,y2)
    • c2=(x1x2)2+(y1y2)2
    • c为奇数,xy的奇偶性会有一个发生改变。
    • c为偶数,xy的奇偶性会同时发生改变或同时不改变。
    • L为奇数,说明边长为奇数的边有奇数条,而多边形是从某一点出发回到这点,最终xy的奇偶性与最初不可能相同。与xn=x0yn=y0矛盾。
  • L0(mod4)可以组成一个边长为L4的正方形
  • L2(mod4)可以组成一个边长分别为L+24L24的矩形。
  • 关于是否存在整点的三角形,只需要枚举第一象限内合法的点。

tc的评测机是真的快~~

// 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 HEREint main(void) {    FindPolygons ___test;    ___test.minimumPolygon(16);    ___test.run_test(-1);    system("pause");}// END CUT HERE
原创粉丝点击