[补]2019HDU杭电多校第五场H

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

参考于:思路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

  魔幻的变量命名)

原文地址:https://www.cnblogs.com/non-/p/11335369.html

时间: 2024-10-11 08:45:21

[补]2019HDU杭电多校第五场H的相关文章

2019 杭电多校 第五场

2019 Multi-University Training Contest 5 补题链接:2019 Multi-University Training Contest 5 罚时爆炸 自闭场 1004 equation (HDU 6627) 题意: 给定一个整数 \(C\) 和 \(N\) 组 \(a_i,b_i\),求 \(∑_{i=1}^N|a_i\cdot x + b_i| = C\) 的所有解,如果有无穷多个解就输出 -1. 思路 分类讨论 分类讨论去绝对值.根据 \(b_i / a_i

[补]2019HDU杭电多校第一场A

不要2000,不要1000,只要998,AC带回家 红小豆在此真诚求教更快的方法orz 参考:https://www.cnblogs.com/DeaphetS/p/11229389.html 场上试图拿数位瞎搞,转移转不动.. 震惊,竟然是n4的四维dp 附赠一份和题解没什么不同但是加了贼快的快读板子才能998ms过的代码_(:з」∠)_ #include<iostream> #include<cstdio> #include<algorithm> #include&l

[2019杭电多校第五场][hdu6629]string matching

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6629 题意求字符串的每个后缀与原串的最长公共前缀之和. 比赛时搞东搞西的,还搞了个后缀数组...队友一说扩展kmp我都自闭了,这不就是扩展kmp的第一步,求原串的每个后缀与原串的最长公共前缀嘛. 需要注意的就是题目准确问的是按照文中所给的代码执行需要判断几次,如果最长公共前缀等于该后缀的长度,则会判断Next[i]次(Next[i]为以i为开始的后缀与原串的最长公共前缀).如果不等,则会判断Next

[2019杭电多校第五场][hdu6625]three arrays(01字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6625 大意为给你两个数组a和b,对应位置异或得到c数组,现在可以将a,b数组从新排序求c数组,使得字典序最小. 大致的做法就是用两个数组中的数字二进制 建两颗字典树,同时记录每个位置的个数.然后在两颗字典树上同时dfs,优先往0-0和1-1方向走,不能走再走0-1,1-0方向. 因为0-0和1-1两种情况不分先后,所以走出来的不一定是最小的,走完得到的c数组要排序. 1 #include<iostr

[2019杭电多校第五场][hdu6628]permutation 1

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6628 题意为求字典序第k小的差异数组,差异数组p满足p[i]=a[i+1]-a[i]. 头铁的爆搜,因为差异数组的范围为[1-n,n-1],所以爆搜的时候可以先将原数组每位+n,记录数字出现的上下界,最后求答案的时候再减去下界即可. 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using n

[2019杭电多校第五场][hdu6624]fraction

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6624 题意为求最小的b满足$a*b^{-1}\equiv x(modp)$. 把式子化简一下: $a\equiv b*x(modp)$ $a=b*x-p*y$ $\because 0<a<b$ $\therefore 0<b*x-p*y<b$ $0<b*x-p*y\Rightarrow \frac{p}{x}<\frac{b}{y}$ $b*x-p*y<b\Right

[2019杭电多校第五场][hdu6630]permutation 2

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6630 题意为求出1-n,n个数的全排列中有多少种方案满足第一位为x,第n位为y,且相邻数字绝对值之差不超过2. 我们可以预处理d数组,定义d[i]表示1-i个数的全排列中以1为第一位,i为第i位且相邻数字绝对值之差不超过2的方案数. 则第i位为i,可以由第i-1位转移,表示i位与i-1位数字绝对值之差为1,则$d[i]+=d[i-1]$,也可以由第i-3位转移,表示第i-1位为i-2,第i-2位为i

HDU 5742 It&#39;s All In The Mind (贪心) 2016杭电多校联合第二场

题目:传送门. 题意:求题目中的公式的最大值,且满足题目中的三个条件. 题解:前两个数越大越好. #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int gcd(int a,int b) { if(!b) return a; return gcd(b,a%b); } int main() { int t; ci

2019 杭电多校 第四场

2019 Multi-University Training Contest 4 补题链接:2019 Multi-University Training Contest 4 1001 AND Minimum Spanning Tree (HDU 6614) 题意 给定一个有 \(N\) 个结点的完全图,编号从 \(1\) 到 \(N\).结点 \(x\) 与结点 \(y\) \((1\leq x, y\leq N, x \neq y)\) 的边的权值为 \(x\) 与 \(y\) 按位与的值,求