小红想知道,自己最终获得了多少分?
第一行输入一个正整数,代表小红扔的桃子数量。
接下来的行,每行输入两个正整数
,代表每个桃子的坐标。
一个整数,代表最终的分数。
3 1 2 2 2 2 1
2
第一个桃子和第二个桃子获得1分。
第二个桃子和第三个桃子获得1分。
5 1 1 1 1 1 1 2 4 3 4
4
共有以下的“桃子对”可以获得分数:[1,2],[1,3],[2,3],[4,5]
使用哈希表记录出现在每个横轴位置和纵轴位置的坐标总数。
分别记录 x 轴相同的位置和 y 轴相同位置的得分。
最后对于位于相同位置的桃子,需要减去这些桃子组合的得分,因为重复计算了。
时间复杂度:
代码如下:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
unordered_map<int, int64_t> xmap;
unordered_map<int, int64_t> ymap;
map<pair<int, int>, int64_t> myMap;
while (n--) {
int x, y;
cin >> x >> y;
xmap[x]++;
ymap[y]++;
myMap[ {x, y}]++;
}
int64_t ret = 0;
// printf("start....\n");
for (auto& e : xmap) {
if (e.second > 1) {
int64_t tmp = (e.second * (e.second - 1));
// // printf("横坐标在 %d 位置的数量为: %d, 得分: %d\n", e.first,
// e.second, tmp);
ret += tmp / 2;
}
}
for (auto& e : ymap) {
if (e.second > 1) {
int64_t tmp = (e.second * (e.second - 1));
// printf("纵坐标在 %d 位置的数量为: %d, 得分: %d\n", e.first,
// e.second, tmp);
ret += tmp / 2;
}
}
for (auto& e : myMap) {
if (e.second > 1) {
int64_t tmp = (e.second * (e.second - 1));
// printf("在位置(%d, %d)位置的数量为: %d, 得分: %d\n", e.first.first,
// e.first.second, e.second, tmp);
ret -= tmp / 2;
}
}
std::cout << ret << std::endl;
return 0;
}
// 64 位输出请用 printf("%lld")
n = int(input())
x_dic, y_dic, coor_dic = {}, {}, {}
res = 0
for _ in range(n):
x, y = list(map(int, input().split()))
if x not in x_dic:
x_dic[x] = 0
if y not in y_dic:
y_dic[y] = 0
if (x,y) not in coor_dic:
coor_dic[(x,y)] = 0
res += (x_dic[x]+y_dic[y]-coor_dic[(x,y)])
x_dic[x] += 1
y_dic[y] += 1
coor_dic[(x,y)] += 1
print(res)