Watchmen are in a danger and Doctor Manhattan together with his friend Daniel Dreiberg should warn them as soon as possible. There are n watchmen on a plane, the i-th watchman is located at point (xi, yi).
They need to arrange a plan, but there are some difficulties on their way. As you know, Doctor Manhattan considers the distance between watchmen i and j to be |xi - xj| + |yi - yj|. Daniel, as an ordinary person, calculates the distance using the formula .
The success of the operation relies on the number of pairs (i, j) (1 ≤ i < j ≤ n), such that the distance between watchman i and watchmen j calculated by Doctor Manhattan is equal to the distance between them calculated by Daniel. You were asked to compute the number of such pairs.
The first line of the input contains the single integer n (1 ≤ n ≤ 200 000) — the number of watchmen.
Each of the following n lines contains two integers xi and yi (|xi|, |yi| ≤ 109).
Some positions may coincide.
Print the number of pairs of watchmen such that the distance between them calculated by Doctor Manhattan is equal to the distance calculated by Daniel.
3 1 1 7 5 1 5
2
6 0 0 0 1 0 2 -1 1 0 1 1 1
11
In the first sample, the distance between watchman 1 and watchman 2 is equal to |1 - 7| + |1 - 5| = 10 for Doctor Manhattan and for Daniel. For pairs (1, 1), (1, 5) and (7, 5), (1, 5) Doctor Manhattan and Daniel will calculate the same distances.
思路:当x或y有一个值相同时,距离相等
#!/usr/bin/python
# -*-coding:utf-8 -*-
n=int(raw_input())
position=[]
for i in range(n):
position.append(map(int,raw_input().split(' ')))
count=0
for i in range(n):
for j in range(i+1,n):
if(position[i][0]==position[j][0] or position[i][1]==position[j][1]):
count=count+1
print count
但是: Time limit exceeded on test 10
#!/usr/bin/python
# -*-coding:utf-8 -*-
import math
from collections import Counter
def f(a):
value=sum((a[key])*(a[key]-1)/2 for key in a)
return value
n=int(raw_input())
position=Counter()
for i in range(n):
position.update([tuple(map(int,raw_input().split(' ')))])
x,y=Counter([k for k,v in position.elements()]),Counter([v for k,v in position.elements()])
value1=f(dict(x))
value2=f(dict(y))
value3=f(dict(position))
print value1+value2-value3
关于Counter类的说明,转载自http://www.pythoner.com/205.html:
1.collections模块
collections模块自Python 2.4版本开始被引入,包含了dict、set、list、tuple以外的一些特殊的容器类型,分别是:
- OrderedDict类:排序字典,是字典的子类。引入自2.7。
- namedtuple()函数:命名元组,是一个工厂函数。引入自2.6。
- Counter类:为hashable对象计数,是字典的子类。引入自2.7。
- deque:双向队列。引入自2.4。
- defaultdict:使用工厂函数创建字典,使不用考虑缺失的字典键。引入自2.5。
文档参见:http://docs.python.org/2/library/collections.html。
2.Counter类
Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。
2.1 创建
下面的代码说明了Counter类创建的四种方法:
2.2 计数值的访问与缺失的键
当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。
2.3 计数器的更新(update和subtract)
可以使用一个iterable对象或者另一个Counter对象来更新键值。
计数器的更新包括增加和减少两种。其中,增加使用update()方法:
减少则使用subtract()方法:
2.4 键的删除
当计数值为0时,并不意味着元素被删除,删除元素应当使用del
。
2.5 elements()
返回一个迭代器。元素被重复了多少次,在该迭代器中就包含多少个该元素。所有元素按照字母序排序,个数小于1的元素不被包含。
2.6 most_common([n])
返回一个TopN列表。如果n没有被指定,则返回所有元素。当多个元素计数值相同时,按照字母序排列。
2.7 fromkeys
未实现的类方法。
2.8 浅拷贝copy
2.9 算术和集合操作
+、-、&、|操作也可以用于Counter。其中&和|操作分别返回两个Counter对象各元素的最小值和最大值。需要注意的是,得到的Counter对象将删除小于1的元素。
3.常用操作
下面是一些Counter类的常用操作,来源于Python官方文档
1
2
3
4
5
6
7
8
9
|
sum
(
c
.
values
(
)
)
# 所有计数的总数
c
.
clear
(
)
# 重置Counter对象,注意不是删除
list
(
c
)
# 将c中的键转为列表
set
(
c
)
# 将c中的键转为set
dict
(
c
)
# 将c中的键值对转为字典
c
.
items
(
)
# 转为(elem, cnt)格式的列表
Counter
(
dict
(
list_of_pairs
)
)
# 从(elem, cnt)格式的列表转换为Counter类对象
c
.
most_common
(
)
[
:
-
n
:
-
1
]
# 取出计数最少的n个元素
c
+=
Counter
(
)
# 移除0和负值
|