18行代码AC_Wet Shark and Bishops CodeForces - 621B(数学推导+映射)

励志用少的代码做高效表达


Problem describe

Today, Wet Shark is given n bishops on a 1000 by 1000 grid. Both rows and columns of the grid are numbered from 1 to 1000. Rows are numbered from top to bottom, while columns are numbered from left to right.

Wet Shark thinks that two bishops attack each other if they share the same diagonal. Note, that this is the only criteria, so two bishops may attack each other (according to Wet Shark) even if there is another bishop located between them. Now Wet Shark wants to count the number of pairs of bishops that attack each other.

Input

The first line of the input contains n (1 ≤ n ≤ 200 000) — the number of bishops.
Each of next n lines contains two space separated integers xi and yi (1 ≤ xi, yi ≤ 1000) — the number of row and the number of column where i-th bishop is positioned. It’s guaranteed that no two bishops share the same position.

Output

Output one integer — the number of pairs of bishops which attack each other.


题意分析

题意:给定一个1000*1000的棋盘,主教棋子的数量n。 规则是若某一主教与其他主教出现在同一条对角线上, 就会互相攻击。 问互相攻击的主教棋子的对数。

首先思考:
若同一主对角线上有n个元素,则在这条对角线上互相攻击棋子的对数为:n*(n-1)/2。(第一个棋子与其余n-1个互相攻击,第二个棋子与其余n-2个互相攻击…即:n-1+n-2+n-3+…+1最后使用等差数列求和公式

因此问题转化为求出棋盘中每条对角线上的棋子个数, 分别代入公式,将结果累加即可

很容易推导出规则:同一主对角线的数相减相等; 同一副对角线的数相加相等;

注意:第一次尝试时,我首先想到利用map容器的归纳性质做映射求解, 但其实直接用数组解即可(貌似大多数的map映射都可简化为数组)。


#include<bits/stdc++.h>
using namespace std;
int main() {
    
    
	ios::sync_with_stdio(false);
	int n, a[4010];	//采用同一数组的不同区间表达两组数
	cin>>n; 
	memset(a,0,sizeof(a));
	for(int i=0;i<n;i++) {
    
    
		int x, y;
		cin>>x>>y;
		a[x+y]++;
		a[x-y+3000]++;
	} 
	long long sum=0;
	for(int i = 0; i < 4000; i++) 
		if(a[i]>1) sum+=(a[i]*(a[i]-1)/2);
		
	cout << sum << endl; 
return 0; } 

天空不会永远阴暗,当乌云退尽的时候,蓝天上灿烂的阳光就会照亮大地。青草照样会鲜绿无比,花朵仍然会蓬勃开放。                 ——《平凡的世界》

猜你喜欢

转载自blog.csdn.net/weixin_43899069/article/details/108663907