zoukankan      html  css  js  c++  java
  • Codeforces Gym 102361A Angle Beats CCPC2019秦皇岛A题 题解

    题目链接https://codeforces.com/gym/102361/problem/A

    题意:给定二维平面上的(n)个点,(q)次询问,每次加入一个点,询问平面上有几个包含该点的直角三角形。

    分析:这是一篇鸽了很久的题解,主要原因就是现场赛的时候这题惨遭卡常,锅++。现在回过头来想这题,主要问题出在现场赛时误判了(map)的时间复杂度,把极角排序的正确想法成功叉掉,以及现场赛时候的共线计数使用了(gcd),使得整体复杂度上升。(但还是有大佬拿gcd思想过了,我太菜了)现在学了一种共线计数的新想法,只需要重载就能实现,于是再用(map)来写一写这道题。。。

    本题思路不难,将直角三角形分为两类,一类是以新加入点为直角顶点的直角三角形,另一类新加入点不作直角顶点。第一种情况,我们将新加入点与原有点之间构成的所有向量加入(map),然后通过点积为零的性质查找垂直的向量个数。(会计数两次,要除以二)另一类采取离线操作,我们将每个原有点当作直角顶点遍历,并将该点与另外原有点构成的向量加入(map),更新(q)个新加入点的直角三角形数量即可。

    AC代码

    #pragma GCC target("avx")
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #include <bits/stdc++.h>
    #define SIZE 2010
    #define rep(i, a, b) for (int i = a; i <= b; ++i)
    #define ll long long
    using namespace std;
    struct Point {
    	ll x, y;
    	Point() {}
    	Point(ll a, ll b) :x(a), y(b) {}
    	Point base() const{
    		if (x < 0 || (x == 0 && y < 0))return Point(-x, -y);
    		return *this;
    	}
    	bool operator<(const Point& b)const {
    		Point p1 = base(); Point p2 = b.base(); //如果共线,考虑是相同的索引
    		return p1.x * p2.y < p1.y * p2.x;
    	}
    	void input() { scanf("%lld %lld", &x, &y); }
    }p[SIZE];
    Point operator *(Point a, ll t) { return Point(a.x * t, a.y * t); }            //向量数乘
    Point operator +(Point a, Point b) { return Point(a.x + b.x, a.y + b.y); }    //向量加法
    Point operator -(Point a, Point b) { return Point(b.x - a.x, b.y - a.y); }    //向量减法
    Point operator / (Point a, ll p) { return Point(a.x / p, a.y / p); }    //向量数乘的除法形式
    double Polarangle(Point a) { return atan2(a.y, a.x); }
    ll __gcd(ll a, ll b) { return b == 0 ? a : __gcd(b, a % b); }
    int n, q, cnt = 1;
    map<Point, int> MAP;
    int main() {
    	scanf("%d %d", &n, &q);
    	int m = q;
    	vector<Point> vec(q + 1);
    	vector<int> res(q + 1);
    	rep(i, 1, n) p[i].input();
    	while (m--) {
    		int ans = 0; Point tp; tp.input();
    		vec[cnt] = tp;
    		rep(i, 1, n) {
    			Point tmp = p[i] - tp;
    			++MAP[tmp];
    		}
    		for (auto it : MAP) {
    			Point tmp(-it.first.y, it.first.x);
    			if (MAP.count(tmp)) ans += MAP[tmp] * it.second;
    		}
    		res[cnt++] = ans / 2;
    		MAP.clear();
    	}
    	rep(i, 1, n) {
    		MAP.clear();
    		rep(j, 1, n) {
    			if (i == j) continue;
    			MAP[p[j] - p[i]]++;
    		}
    		rep(j, 1, q) {
    			Point tp = vec[j] - p[i];
    			tp = Point(-tp.y, tp.x);
    			res[j] += MAP.count(tp) ? MAP[tp] : 0;
    		}
    	}
    	rep(i, 1, q) printf("%d
    ", res[i]);
    }
    
  • 相关阅读:
    用JavaScript 来创建 mac os x 程序这样是否好
    hadoop的namenode无法启动的解决的方法
    Cocos2d-x新建模板编译问题总汇
    JBoss AS 7之基本配置和部署(The Return Of The King)
    margin和padding的学习
    HDU 1232 畅通project
    C/C++程序内存分类
    iOS 推断设备为iPhone还是iPad
    or1200中载入存储类指令说明
    专业词汇-计算机:占位符
  • 原文地址:https://www.cnblogs.com/st1vdy/p/11664520.html
Copyright © 2011-2022 走看看