找规律题
以 y = -x 和 y = x 为分界线,会发现 上面 和 右边 的横线依次是 2,4,6,8……;下边 和 左边 的横线依次是 1,3,5,7……;等差数列求和,再根据不同位置做微调。
我这里是以象限划分的,每个象限找一个基本点,第一象限就是 (n,n);第二象限 就是 (-n,n)……
需要注意的是,第三象限,离 对角线上的点有一个单位长度的偏差,特殊处理。因为这个偏差,在算第三象限基本点长度的时候也要调整。
注意:百分百数据范围是 -10^9 ~ 10^9,会超 int !!要用 long long
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL add1(LL n){ // 1,3,5,,,
LL ans;
LL cnt = 2 * n - 1;
ans = ((1 + cnt) * n) / 2;
return ans;
}
LL add2(LL n){ // 2,4,6,,,
LL ans;
LL cnt = 2 * n;
ans = ((2 + cnt) * n) / 2;
return ans;
}
LL max(LL a,LL b){
if(a>b) return a;
else return b;
}
int main(){
LL x,y;
cin>>x>>y;
LL m;// m 是绝对值大的那个值
LL tmp = 0;
if(x>=0){
if(y>=0){//第一象限 (3,3)
m = max(x,y);
tmp += 2 * add1(m);
tmp += add2(m);
tmp += add2(m - 1);
if(m == x){// x 更大 (3,2)
tmp += (x - y);
}
else{// y 更大 (2,3)
tmp -= (y - x);
}
}
else{//第四象限 (3,-3)
LL _y = -y;
m = max(x,_y);
tmp += (2 * add1(m));
tmp += (2 * add2(m));
if(m == x){ // (3,-1) 减
tmp -= (x - _y);
}
else{ // (2,-3)
tmp += (_y - x);
}
}
}
else{
if(y>=0){//第二象限
LL _x = -x;
m = max(_x,y);
tmp += (2 * add1(m));
tmp += (2 * add2(m - 1));
if(m == _x){// (-3,2) 下边,减
tmp -= (_x - y);
}
else{ // (-2,3) 右边,加
tmp += (y - _x);
}
}
else{//第三象限 把横坐标右移一位再比较 (-4,-3)
LL _x = -(x + 1);
LL _y = -y;
m = max(_x,_y);
tmp += add1(m);
tmp += add1(m+1);
tmp += (2 * add2(m));
if(m == _x){ // 上边 加 (-4,-2) -> (-3,-2)
tmp += (_x - _y);
}
else{// 右边 减 (-3,-3) -> (-2,-3)
tmp -= (_y - _x);
}
}
}
cout<<tmp<<endl;
return 0;
}