zoukankan      html  css  js  c++  java
  • JNUOJ 1187

    Time Limit: 10000ms
    Memory Limit: 262154KB
    64-bit integer IO format: %lld      Java class name: Main

    木衫同学和凌小小都是军队的指挥官,他们共同管理着一队哨兵,每个哨兵都有一个位置(x,y)。但是木衫同学和凌小小计算距离的方法不一样,木衫同学计算第i个人和第j个人的距离利用以下公式 |xi - xj| + |yi - yj|,而凌小小计算时利用以下公式sqrt( (xi-xj)^2+(yi-yj)^2 )。现在问有多少组哨兵,他们之间的距离运用两种公式计算出来的结果是一样的。

    Input

    第一行输入一个整数T,代表有T组数据
    每组数据第一行输入n(1 ≤ n ≤ 200000),代表哨兵的个数。
    下面的n行,每行有两个整数,代表当前哨兵的坐标,(|xi|, |yi| ≤ 10^9)。

    Output

    每组数据输出一行,这一行只有一个整数,即符合条件的哨兵的组数。

    Sample Input

    2
    3
    1 1
    7 5
    1 5
    6
    0 0
    0 1
    0 2
    -1 1
    0 1
    1 1

    Sample Output

    2
    11


    单纯暴力当然是要超时的……其实满足|xi - xj| + |yi - yj| = sqrt( (xi-xj)^2+(yi-yj)^2 )的两个点,只能是在同一条水平线或者同一条竖直线上

    所以可以把不用计算两个距离,而是通过判断是否在同一条水平线或者同一条竖直线上来判断是否满足|xi - xj| + |yi - yj| = sqrt( (xi-xj)^2+(yi-yj)^2 )
     1 #include<cstdio>
     2 #include<cmath>
     3 #include<cstdlib>
     4 long long ans;
     5 int n;
     6 struct type{
     7     double x,y;
     8 }p[200000+5];
     9 bool check(type a,type b)
    10 {
    11     if(a.x == b.x || a.y == b.y) return true;
    12     return false;
    13 }
    14 int main()
    15 {
    16     int t;
    17     scanf("%d",&t);
    18     while(t--)
    19     {
    20         scanf("%d",&n);
    21         for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    22         ans=0;
    23         for(int i=1;i<n;i++)
    24         {
    25             for(int j=i+1;j<=n;j++)
    26             {
    27                 if(check(p[i],p[j])) ans++;
    28             }
    29         }
    30         printf("%lld
    ",ans);
    31     }
    32 }

    这大概要耗时4秒左右。

    所以可以考虑把用map把出现过的水平线(y=k的k作为key值)或者竖直线记录下来(x=k的k作为key值),然后把出现过的两个哨兵在相同的点上的情况也记录下来,

    这样,每输入一个哨兵的坐标,ans+= “与他在同一条水平线上的人” + “与他在同一条竖直线上的人” - “与他在同一个坐标上的人(因为这样的人重复算了两次)”

     1 #include<cstdio>
     2 #include<map>
     3 using namespace std;
     4 typedef long long ll;
     5 pair<ll,ll> now;
     6 map<ll,ll> a,b;
     7 map<pair<ll,ll>,ll> same;
     8 int n;
     9 ll ans,x,y;
    10 int main()
    11 {
    12     int t;
    13     scanf("%d",&t);
    14     while(t--)
    15     {
    16         a.clear();b.clear();same.clear();
    17         ans=0;
    18         scanf("%d",&n);
    19         for(int i=1;i<=n;i++)
    20         {
    21             scanf("%d%d",&x,&y);
    22             ans=ans+a[x]+b[y]-same[make_pair(x,y)];
    23             a[x]++;
    24             b[y]++;
    25             same[make_pair(x,y)]++;
    26         }
    27         printf("%d
    ",ans);
    28     }
    29 }

     这样耗时大概是1秒左右。

  • 相关阅读:
    去掉字符串中的空格
    在线工具和云服务推荐
    Tomcat 8080端口被占用解决方法
    MySQL 相关总结
    去除Jsp页面空白行
    linux 常用命令
    最近面试Android的一些面试题
    Android动态加载Activity原理
    Android动态资源加载原理和应用
    利用DexClassLoader动态加载dex文件
  • 原文地址:https://www.cnblogs.com/dilthey/p/6819411.html
Copyright © 2011-2022 走看看