这个题是我第二次遇见的曼哈顿距离题目(但这道题要容易一些,因为我上回写的是K维的曼哈顿);
回忆一下什么是曼哈顿距离:
对于二维曼哈顿距离几何定义:
然后可以把d(1,2)分情况变形:
1.x1-x2>=0&&y1-y2>=0可得:d(1,2)=x1-x2+y1-y2;
2.x1-x2>=0&&y1-y2<0可得:d(1,2)=x1-x2+y2-y1;
3.x1-x2<0&&y1-y2>=0可得:d(1,2)=x2-x1+y1-y2;
4.x1-x2<0&&y1-y2<0可得:d(1,2)=x2-x1+y2-y1;
然后我可以把一对点的x和y合并变形可得:
然后问题就是如何求值了:这个可以很明显发现(x1,y1)的系数和(x2,y2)的系数相对应(也就是每个状态对应相等);
然后我就可以令系数-1为1,系数1为0,然后就可以利用枚举二进制了(其实这里可以根据自己想的来令,因为二进制只有0,1);意思就是这个意思:
所以看了看,明显枚举没问题;
所以枚举二进制状态即可(求最大曼哈顿距离);
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e4+10;
int a[maxn][2],n;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d %d",&a[i][0],&a[i][1]);//利用一个二维数组存坐标,当然也可以用结构体或者pair
}
int ans1=0,ans2=0,Max=0;
int f1,f2;//记录系数
for(int i=0;i<n;i++){//,枚举
for(int j=i+1;j<n;j++){
int sum =0;
for(int k=0;k<=3;k++){//枚举状态 一共就00 01 10 11四种状态
for(int u=0;u<=1;u++){//位移1来用&来判断对应的状态
if(u==0){//右边第一个
if(k&(1<<u)){///这就是上面分析时候说的1&1时,系数就为-1;反之为1;这个系数是从右往左枚举的哈,这样就可以理解了
f2=-1;
}else{
f2=1;
}
}else{//右边第二个
if(k&(1<<u)){
f1=-1;
}else{
f1=1;
}
}
}
sum+=(f1*a[i][0]+f2*a[i][1]-(f1*a[j][0]+f2*a[j][1]));
if(sum>Max){//存最大值
Max=sum;
ans1=i+1;ans2=j+1;//记录下标
}
sum=0; //每次更新值,因为每次状态都会变值
}
}
}
printf("%d %d\n",ans1,ans2);
return 0;
}