51nod 距离之和最小v1 v2 v3

基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
X轴上有N个点,求X轴上一点使它到这N个点的距离之和最小,输出这个最小的距离之和。
Input
第1行:点的数量N。(2 <= N <= 10000)
第2 - N + 1行:点的位置。(-10^9 <= P[i] <= 10^9)
Output
输出最小距离之和
Input示例
5
-1
-3
0
7
9
Output示例
20

思路:奇偶讨论中位数。

Code:

#include <bits/stdc++.h>
using namespace std;
const int AX= 1e4+66;
int a[AX];
int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);
	int n;
	cin >> n;
	for( int i = 0 ; i < n ; i++ ){
		cin >> a[i];
	}
	int k;
	sort(a,a+n);
	if( n % 2 ){
		k = a[n/2];
	}else{
		k = (a[n/2] + a[n/2-1])/2;
	}
	long long res = 0;
	for( int i = 0 ; i < n ; i ++ ){
		res += fabs(k-a[i]);
	}
	cout << res << endl;
	return 0;
}
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
三维空间上有N个点, 求一个点使它到这N个点的曼哈顿距离之和最小,输出这个最小的距离之和。
点(x1,y1,z1)到(x2,y2,z2)的曼哈顿距离就是|x1-x2| + |y1-y2| + |z1-z2|。即3维坐标差的绝对值之和。
Input
第1行:点的数量N。(2 <= N <= 10000)
第2 - N + 1行:每行3个整数,中间用空格分隔,表示点的位置。(-10^9 <= X[i], Y[i], Z[i] <= 10^9)
Output
输出最小曼哈顿距离之和。
Input示例
4
1 1 1
-1 -1 -1
2 2 2
-2 -2 -2
Output示例
18
思路:
跟上面的思路一样,但是这个是三维的,所以每一维分开讨论。
Code:
#include <bits/stdc++.h>
#define LL long long 
using namespace std;
const int AX = 1e4+66;
int x[AX];
int y[AX];
int z[AX];
int main(){
	int n ;
	cin >> n ;
	LL x1 = 0 , y1 = 0 ,z1 = 0;
	for( int i = 0; i < n ; i++ )
		cin >> x[i] >> y[i] >> z[i];
	sort( x , x + n );
	sort( y , y + n );
	sort( z , z + n );
	if( n % 2 ) x1 = x[n/2];
	else x1 = (x[n/2] + x[n/2-1] ) / 2;
	if( n % 2 ) y1 = y[n/2];
	else y1 = (y[n/2] + y[n/2-1] ) / 2;
	if( n % 2 ) z1 = z[n/2];
	else z1 = (z[n/2] + z[n/2-1] ) / 2;
	
	LL res = 0;
	for( int i = 0 ; i < n ; i++ ){
		res += abs( x1 - x[i] );
		res += abs( y1 - y[i] );
		res += abs( z1 - z[i] );
	}
	cout << res << endl;
	return 0 ;
}


基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i]。点P到点P[i]的带权距离 = 实际距离 * P[i]的权值。求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和。
Input
第1行:点的数量N。(2 <= N <= 10000)
第2 - N + 1行:每行2个数,中间用空格分隔,分别是点的位置及权值。(-10^5 <= X[i] <= 10^5,1 <= W[i] <= 10^5)
Output
输出最小的带权距离之和。
Input示例
5
-1 1
-3 1
0 1
7 1
9 1
Output示例
20
思路:权值就当做这个点重复出现的次数。
Code:
#include <bits/stdc++.h>
#define LL long long 
using namespace std;
const LL AX = 1e4+66;
struct Node{
	LL x,v;
}a[AX];
bool cmp( const Node &a , const Node &b ){
	return a.x < b.x;
}
int main(){
	ios::sync_with_stdio(false); cin.tie(0);
	LL n ;
	cin >> n ;
	LL len = 0 ;
	for( LL i = 0 ; i < n ; i++ ){
		cin >> a[i].x >> a[i].v;
		len += a[i].v;
	}
	sort( a , a + n , cmp );
	LL tmp = len / 2 + 1 ;
	LL mm;
	for( LL i = 0 ; i < n ; i++ ){
		if( tmp > a[i].v ){
			tmp -= a[i].v;
		}else{
			mm = a[i].x;
			break;
		}
	}
	LL res = 0;
	for( LL i = 0 ; i < n ; i++ ){
		res += abs(a[i].x-mm)*a[i].v;
	}
	cout << res << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值