/* 可用暴力破解的方法,思路如下: 先假设对称轴存在,且其为 x = xmid,那么对称轴肯定为为左端和最右端中点的平均数 xmid = ( xmin + xmax) / 2 如果x = x0真为对称轴,对任意的 xi,都会有 xj = 2 * xmid - xi; 鉴于求xmid涉及除以2,但是判断的时候,却可以用对称轴横坐标的两倍来判断,出于精度和误差方面的考虑,我们便可不用除法了,直接 xmid = xmin + xmax; 但判断时,注意变成找到满足 xj = xmid - xi的j 思路来自: http://blog.csdn.net/acvay/article/details/43015507 */
#include <iostream> using namespace std; const int maxn = 1005; int x[maxn], y[maxn], xmid, n; bool solve() { for (int i = 0; i < n; i++) { bool flag = 1; //为1说明没找到该点关于对称轴的对称点 for (int j = 0; j < n; j++) if (x[i] + x[j] == xmid && y[i] == y[j]) { flag = 0; break; } if (flag) return false; } return true; } int main() { int t, mini, maxi; //后两个变量为横坐标最小时对应的i,和横坐标最大时对应的i cin >> t; while (t--) { mini = maxi = 0; cin >> n; for (int i = 0; i < n; i++) { cin >> x[i] >> y[i]; if (x[i] < x[mini]) mini = i; if (x[i] > x[maxi]) maxi = i; } xmid = x[mini] + x[maxi]; if ( solve() ) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }
/* edition2 只能算版本2,而不能算法2,因为思路本质上和法1时一模一样的 有几个区别,不过算是细节上的区别: 1. 用到了set和set有关的函数,例如insert()和find(),我子集做题时用到的更多的时map,所以set的用法可以从这里学习一下 2. 求对称轴的横坐标时,用的是所有边横坐标 / n,但在输入以后,把横坐标扩大n倍,以避免小数误差。 然而其实法1的借鉴的blog里,就是这么写的,只是把n换为了2罢了... 不过,我在法1的代码,没有完全用法1借鉴的博客,由于发现判断时要乘以2,所以该除的地方没除,该乘的没乘 参考blog: http://blog.csdn.net/majing19921103/article/details/43275901 */
#include <iostream> #include <set> using namespace std; int n, sum; typedef pair<int, int> P; set<P> loc; //location void solve() { bool flag = true; for (set<P>::iterator i = loc.begin(); i != loc.end(); i++) { P p = *i; if (loc.find(P(2 * sum - p.first, p.second)) == loc.end()) { flag = false; break; } } if (flag) cout << "YES" << endl; else cout << "NO" << endl; } int main() { int t, x, y; cin >> t; while (t--) { loc.clear(); //此处很容易忘记,小心! sum = 0; cin >> n; for (int i = 0; i < n; i++) { cin >> x >> y; loc.insert(P(x * n, y)); sum += x; } solve(); } return 0; }