红小豆又被奇怪的东西卡住了
参考于:思路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; }
魔幻的变量命名)