内容目录
中位数 贪心
x,y 分开考虑
显然中间那个点一定最省
1.
奇数 显然中间那个点一定最省 之后走一步答案必会增加,因此中间和4个方向一定最省,另外4个方向增加是对应2个方向的和
2
偶数
判定整个范围会超时
枚举牛而非整个区间,否则TLE
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<iostream> #include<functional> #include<algorithm> #define MAXN (10000 + 10) #define INF 400000000 + 10 using namespace std; int x[MAXN],y[MAXN]; int a[4][2]={{1,0},{-1,0},{0,-1},{0,1}}; int node[MAXN][2]; int n; int sum(int nx,int ny) { int tot=0; for (int i=1;i<=n;i++) { tot+=abs(x[i]-nx)+abs(y[i]-ny); } return tot; } int b(int x,int y) { for (int i=1;i<=n;i++) if (node[i][0]==x&node[i][1]==y) return true; return false; } void find(int &minway,int &ans,int x,int y) { int nowtot=sum(x,y); if (nowtot<minway) { ans=1; minway=nowtot; } else if (nowtot==minway) ans++; } int calc() { int m=(1+n)/2; if (n%2) { if (!b(x[m],y[m])) { printf("%d",sum(x[m],y[m])); return 1; } else { int minway=INF,ans=0; for (int i=0;i<4;i++) { find(minway,ans,x[m]+a[i][0],y[m]+a[i][1]); } printf("%d",minway); return ans; } } else { int ans=0; for (int i=1;i<=n;i++) { if (x[m]<=node[i][0]&&node[i][0]<=x[m+1]&&y[m]<=node[i][1]&&node[i][1]<=y[m+1]) ans++; } ans=(x[m+1]-x[m]+1)*(y[m+1]-y[m]+1)-ans; printf("%d",sum(x[m],y[m])); return ans; } } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d%d",&x[i],&y[i]); node[i][0]=x[i]; node[i][1]=y[i]; } sort(x+1,x+n+1); sort(y+1,y+n+1); printf(" %dn",calc()); return 0; }