红小豆又被奇怪的东西卡住了

参考于:思路https://www.cnblogs.com/st1vdy/p/11309280.html

    样例https://www.cnblogs.com/dd-bond/p/11308155.html

 

HDU-6631 line symmetric

  多边形轴对称类问题。关于多边形轴对称目前可以公开的情报可见第一篇blog的大佬画的图,主要就是奇偶问题。本题主要思路是枚举实现找轴和验证对称,注意判自交的方式。

  初步认识可以做一下hdu3902。

  在下还是专注于讲心路历程。又是按思路拍键盘拍出类似的东西但就是不过的情节,于是开始逐字节比对。期间发生了诸如“难道cross有顺序问题?改了改了……”“为什么这里不是用本来的点的?非常奇怪但改了改了……”“加个sgn看看!”的改动,但还是没有过。在被宿舍锁在外面之前,队友把<0改成<eps,然后过了,于是满头问号地回了。因为多校有数据可以下,所以可以看到队友改动之前只有一个样例没过,而这道题在hdu的discuss里有位大佬提供了两个样例,其中一个在改动前的版本可以过但改动之后不能过了,这位大佬就是第二篇blog的大佬。不甘心的红小豆重新学习这位大佬的思路,对着大佬画的样例图陷入沉思……这好像按照原来的思路就是对的呀,就是这个比对的点。。。没错就是那个改动过的点,其实还是应该用本来的点,而第一篇blog交上去是能巧妙ac的_(:з」∠)_改回来之后,<0的条件也能ac了,<-eps也能ac了,第二位的大佬的样例也能过了,腰不酸腿不痛浑身都emmm犯困了。。至于红小豆为什么没改之前没过,emmm因为隔一个点找轴的情况里忘了测中间那个点在不在轴上了┓( ´∀` )┏

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long LL;

const double eps = 1e-8;

#define CN(a) const node &a 
typedef long long LL;
int n, t;
struct node
{
    double x, y;
}po[1005], re;

double dot(CN(a), CN(b), CN(c)) { return (a.x - b.x) * (a.x - c.x) + (a.y - c.y) * (a.y - b.y); }

double cro(CN(a), CN(b), CN(c)) { return (a.x - b.x) * (c.y - a.y) - (c.x - a.x) * (a.y - b.y); }

int jg(CN(m), CN(om), int a, int b)
{
    bool f1 = 0, f2 = 0;
    if (cro(po[a], m, om)) {
        int p1 = a - 1, p2 = a + 1;
        if (p1 < 1)p1 += n;
        if (p2 > n)p2 -= n;
        if (cro(po[p1], m, om) * cro(po[p2], m, om) < 0 ||
            cro(po[p1], m, om) * cro(po[a], m, om) < 0 ||
            cro(po[p2], m, om) * cro(po[a], m, om) < 0)
            f1 = 1;
    }
    else  f1 = 1;
    if (cro(po[b], m, om)) {
        int p1 = b - 1, p2 = b + 1;
        if (p1 < 1)p1 += n;
        if (p2 > n)p2 -= n;
        if (cro(po[p1], m, om) * cro(po[p2], m, om) < 0 ||
            cro(po[p1], m, om) * cro(po[b], m, om) < 0 ||
            cro(po[p2], m, om) * cro(po[b], m, om) < 0)
            f2 = 1;
    }
    else f2 = 1;
    if (f1 && f2)return 1;
    return 0;
}

int main()
{
    scanf("%d", &t);
    int num;
    node mid, oum, p1, p2;
    bool ok;
    while (t--) {

        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%lf%lf", &po[i].x, &po[i].y);

        if (n <= 4) { cout << "Y" << endl; continue; }
        ok = 0;
        for (int i = 1; i <= n; i++) {
            num = 0;
            p1 = po[i], p2 = po[i % n + 1];
            mid.x = (p1.x + p2.x) / 2.0;
            mid.y = (p1.y + p2.y) / 2.0;
            oum.x = mid.x + p1.y - mid.y;
            oum.y = mid.y + mid.x - p1.x;
            if (n % 2)
                if (cro(po[(i + n / 2) % n + 1], mid, oum))num++;
            int cnt = n / 2 - 1, l = i - 1, r = i + 2;
            while (cnt--) {
                if (l < 1)l += n;
                if (r > n)r -= n;
                node mx;
                mx.x = (po[l].x + po[r].x) / 2.0;
                mx.y = (po[l].y + po[r].y) / 2.0;
                if (dot(mid, po[i], mx) != 0 || dot(mx, po[l], mid) != 0) {
                    num++;
                    num += jg(mid, oum, l, r);
                }
                l--, r++;
            }
            if (num <= 1) { ok = 1; break; }
        }
        if (ok) { cout << "Y" << endl; continue; }

        for (int i = 1; i <= n; i++) {
            num = 0;
            p1 = po[i], p2 = po[(i + 1) % n + 1];
            mid.x = (p1.x + p2.x) / 2.0;
            mid.y = (p1.y + p2.y) / 2.0;
            oum.x = mid.x + p1.y - mid.y;
            oum.y = mid.y + mid.x - p1.x;
            if (cro(po[i % n + 1], mid, oum))num++;
            if (!(n % 2))
                if (cro(po[(i + n / 2) % n + 1], mid, oum))num++;
            int cnt = n / 2 - 1, l = i - 1, r = i + 3;
            while (cnt--) {
                if (l < 1)l += n;
                if (r > n)r -= n;
                node mx;
                mx.x = (po[l].x + po[r].x) / 2.0;
                mx.y = (po[l].y + po[r].y) / 2.0;
                if (dot(mid, po[i], mx) != 0 || dot(mx, po[l], mid) != 0) {
                    num++;
                    num += jg(mid, oum, l, r);
                }
                l--, r++;
            }
            if (num <= 1) { ok = 1; break; }
        }
        if (ok)cout << "Y" << endl;
        else cout << "N" << endl;
    }

    return 0;
}
line symmetric

 

  魔幻的变量命名)

 posted on 2019-08-11 16:20  Nonad  阅读(160)  评论(0编辑  收藏  举报