码迷,mamicode.com
首页 > 其他好文 > 详细

[2016-03-08][codeforces][651][C][Watchmen]

时间:2016-03-10 23:36:15      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:

[2016-03-08][codeforces][651][C][Watchmen]
  • 时间:2016-03-08 23:29:35 星期二
  • 题目编号:CF 651 C. Watchmen
  • 题目大意:
    • 给定n个点,求n个点有多少对点使得 |x1 - x2| + |y1 - y2| = ((x1 - x2)^2 + (y1 - y2)^2)^0.5
  • 输入:n n对点
  • 输出:对数
  • 分析:
    • 如果两个点x,y坐标都不一样,那么前者是直角三角形两边之和,后者是三角形的第三条变,所以,满足上式当且仅当两个点x坐标或者y坐标一样
  • 方法:
    • 根据分析,问题等价于求n个点中,有几对点x坐标或者y坐标相同
    • 枚举所有坐标,分别计算对应x,y相同的数目,减去坐标相同的点
    • 直接枚举i,然后枚举j会超时,
    • 这时候先sort按x排序,然后x相同的一定相邻,直接计算相邻的数目即可
    • 然后再sort按y排序,同上,
    • 第三次枚举相同的就不用再sort,直接在y排序完之后的基础上比较即可
  • 解题过程遇到问题:
    • 当数量比较大的时候,ans或者是cnt*(cnt - 1)会超过int

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long LL;
#define CLR(x,y) memset((x),(y),sizeof((x)))
#define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))
#define FORD(x,y,z) for(int (x)=(y);(x)>=(z);--(x))
#define FOR2(x,y,z) int (x);for((x)=(y);(x)<(z);++(x))
#define FORD2(x,y,z) int (x);for((x)=(y);(x)>=(z);--(x))



const int maxn = 200000 + 10;
struct Point{
        int x,y;
        bool operator == (const Point & a)const {
                return a.x==x && a.y == y;
        }
}p[maxn];
bool cmp1(Point & a,Point & b){
        return a.x < b.x || (a.x == b.x && a.y < b.y);
}
bool cmp2(Point & a,Point & b){
        return a.y < b.y || (a.y == b.y && a.x < b.x);
}
int main(){
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int n;LL ans = 0;
        scanf("%d",&n);
        FOR(i,0,n)     scanf("%d%d",&p[i].x,&p[i].y);
        sort(p,p+n,cmp1);
        for(int i = 0;i < n ;){
                int cnt = 0;
                FOR2(j,i,n){
                        if(p[j].x == p[i].x)    ++cnt;
                        else break;
                }
                ans += (long long)1 * (cnt - 1)*cnt/2;
                i = j;
        }
        sort(p,p+n,cmp2);
        for(int i = 0;i < n ;){
                int cnt = 0;
                FOR2(j,i,n){
                        if(p[j].y == p[i].y)    ++cnt;
                        else break;
                }
                ans += (long long)1*(cnt - 1)*cnt/2;
                i = j;
        }
        for(int i = 0;i < n ;){
                int cnt = 0;
                FOR2(j,i,n){
                        if(p[j] == p[i])        ++cnt;
                        else break;
                }
                ans -= (long long)1*(cnt - 1)*cnt/2;
                i = j;
        }
        printf("%I64d\n",ans);
        return 0;
}  









[2016-03-08][codeforces][651][C][Watchmen]

标签:

原文地址:http://www.cnblogs.com/qhy285571052/p/5263917.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!