Building A New Barn

参考: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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值