参考:https://blog.csdn.net/u011815404/article/details/80820537
自己一开始写的版本超时了,我来分析一下自己的逻辑,然后和参考代码比较一下。
sort都是排两次,但是可能结构体交换位置次数是单纯数组的两倍
N为奇数且没有放牧点与这个最优点重合:
A:一个for里面做了计算和if-else判定
B: 判定加计算分别用掉了两个for
N为奇数且有放牧点与这个最优点重合:
A:检测到重复1-N次不定——1个for,周边点计算——4个for
B: 一个for检测是否重合,周边点计算——4个for
N为偶数:
A:一个for里面做了计算和if-else判定
B: cnt = (ed.x - st.x + 1) * (ed.y - st.y + 1) ;
cnt*(1-2)次for——忽略了偶数个点产生的区间点其所求的曼哈顿值是相同的
改进之后两次for:计算和判定
所以花费时间最多的就是没有改进前的N为偶数的情况,改进之后就过了
自己最后的AC代码:|
// A
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxn 10005
#define inf 0x3f3f3f3f
int N, x[maxn], y[maxn];
typedef struct point {
int x, y;
} point;
point p[maxn], st, ed, tmp;
int isvali(point a)
{
if (a.x >= -10000 && a.x <= 10000 && a.y >= -10000 && a.y <= 10000) return 1;
return 0;
}
int dir[][2] = {{1, 0}, { -1, 0}, {0, -1}, {0, 1} };
int main()
{
#ifdef LOCAL
freopen("test_data.in.txt", "r", stdin);
//freopen("test_result.out.txt", "w", stdout);
#endif
int i, j, k, a, b, sum , cp , cnt, ans;
scanf("%d", &N) ;
for (i = 1; i <= N; ++i)
{
scanf("%d%d", &p[i].x, &p[i].y);
x[i] = p[i].x ; y[i] = p[i].y ;
}
sort(x + 1, x + N + 1);
sort(y + 1, y + N + 1);
if (N % 2)
{
a = x[ N / 2 + 1 ], b = y [ N / 2 + 1 ];
sum = 0;
for ( i = 1; i <= N ; ++i )
{
sum += (abs(a - p[i].x) + abs(b - p[i].y));
if (a == p[i].x && b == p[i].y)
{
cnt = 0, ans = inf;
for (j = 0; j < 4; ++j)
{
cp = 0;
tmp.x = a + dir[j][0];
tmp.y = b + dir[j][1];
if (isvali(tmp))
{
for ( k = 1; k <= N; ++k) cp += (abs(tmp.x - p[k].x) + abs(tmp.y - p[k].y));
if (cp < ans)
{
cnt = 1;
ans = cp;
}
else if (cp == ans)
{
++cnt;
}
}
}
printf("%d %d\n", ans, cnt);
return 0;
}
}
printf("%d 1\n", sum);
}
else
{
st.x = x[N / 2]; ed.x = x[N / 2 + 1];
st.y = y[N / 2]; ed.y = y[N / 2 + 1];
cnt = (ed.x - st.x + 1) * (ed.y - st.y + 1) ;
ans = 0;
for (i = 1; i <= N; ++i)
{
if (p[i].x >= st.x && p[i].x <= ed.x && p[i].y >= st.y && p[i].y <= ed.y) --cnt;
ans += (abs(st.x - p[i].x) + abs(st.y - p[i].y));
}
printf("%d %d\n", ans, cnt);
}
return 0;
}
// 改进之后的B
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxn 10005
#define inf 0x3f3f3f3f
int N;
typedef struct point {
int x, y;
bool operator == (const point& a)const
{
return x == a.x && y == a.y;
}
} point;
point p[maxn], tm, mt;
int cmp1(point a, point b)
{
return a.x < b.x;
}
int cmp2(point a, point b)
{
return a.y < b.y;
}
int search(point a)
{
for (int i = 1; i <= N; ++i)
{
if (a == p[i]) return 1;
}
return 0;
}
int comp(point a)
{
int sum = 0;
for (int i = 1; i < N + 1; ++i)
{
sum += (abs(a.x - p[i].x) + abs(a.y - p[i].y));
}
return sum;
}
int isvali(point a)
{
if (a.x >= -10000 && a.x <= 10000)
{
if (a.y >= -10000 && a.y <= 10000) return 1;
}
return 0;
}
int dir[][2] = {{1, 0}, { -1, 0}, {0, -1}, {0, 1}};
int main()
{
#ifdef LOCAL
freopen("test_data.in.txt", "r", stdin);
//freopen("test_result.out.txt", "w", stdout);
#endif
int i;
cin >> N;
for (i = 1; i <= N; ++i) scanf("%d%d", &p[i].x, &p[i].y);
if (N % 2)
{
sort(p + 1, p + N + 1, cmp1);
tm.x = p[N / 2 + 1].x;
sort(p + 1, p + N + 1, cmp2);
tm.y = p[N / 2 + 1].y;
if (search(tm))
{
int cnt = 0, ans = inf, cp;
point jy ;
for (i = 0; i < 4; ++i)
{
jy.x = tm.x + dir[i][0];
jy.y = tm.y + dir[i][1];
if (isvali(jy))
{
cp = comp(jy);
if (cp < ans)
{
cnt = 1;
ans = cp;
}
else if (cp == ans)
{
++cnt;
}
}
}
printf("%d %d", ans, cnt);
}
else
{
printf("%d 1", comp(tm));
}
}
else
{
sort(p + 1, p + N + 1, cmp1);
tm.x = p[N / 2].x; mt.x = p[N / 2 + 1].x;
sort(p + 1, p + N + 1, cmp2);
tm.y = p[N / 2].y; mt.y = p[N / 2 + 1].y;
int ans = comp(tm), cnt = (mt.x - tm.x + 1) * (mt.y - tm.y + 1) ;
for (i = 1; i <= N; ++i)
{
if(p[i].x>=tm.x&&p[i].x<=mt.x&&p[i].y>=tm.y&&p[i].y<=mt.y) --cnt;
}
printf("%d %d", ans, cnt);
}
return 0;
}