gym104366 I.Subsetting and Summing

题意就是给你n(1<=n<=1e5)个三维向量,向量的坐标数据范围x1, x2, x3为−1e4≤x1, x2, x3≤1e4

从这n个向量中选一些向量合成一个新向量(x,y,z), 问所有选取方案当中(|x|+|y|+|z|)的最大值

使得(|x|+|y|+|z|)最大的向量(x,y,z)中的三个参数可能有正有负对吧, 假设情况是(8,-10,9)那么(|x|+|y|+|z|)这个东西取绝对值之后就是x-y+z, 所以一个自然的解法就出来了。

对于每个向量它取不取的依据就是(x1-x2+x3), 如果这个东西>0, 我们自然会选它。

综上, 我们只需要遍历一共2的3次方种符号正负的情况就行了。

代码如下

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define fi first
#define se second
#define rep(i, a, n) for (int i = a; i < n; i++)
#define per(i, a, n) for (int i = n - 1; i >= a; i--)
#define pb push_back
#define cntbit __builtin_popcountll
#define pii pair<int, int>
#define vii vector<pair<int, int>>
#define ll long long
#define all(x) (x).begin(), (x).end()
using namespace std;
const int inf = 1ll<<62;
const int mod = 1e9+7;
void chkmax(int &a,int b){
    a=max(a,b);
}
void chkmin(int &a,int b){
	a=min(a,b);
}
void add(int &a, int b) {
    a += b;
    if (a >= mod) a -= mod;
}
void sub(int &a,int b){
	a-=b;
	if(a<0) a+=mod;
}
int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}
int qmi(int a, int b) {
    int res = 1;
    for (; b; b >>= 1) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
    }
    return res;
}
const int N = 200010;

int n; 
struct ve{
	int x,y,z;
};
ve a[100010];
void solve() {
	cin>>n;
	rep(i,1,n+1){
		cin>>a[i].x>>a[i].y>>a[i].z;
	}
	int ans=0;
	rep(i,0,8){
		int now=0;
		rep(j,1,n+1){
			int sign[3]={1,1,1};
			rep(k,0,3) sign[k]=((i>>k)&1?-1:1);
			int val=0;
			val-=sign[0]*a[j].x;
			val-=sign[1]*a[j].y;
			val-=sign[2]*a[j].z;
			if(val>0) now+=val;
		}
		ans=max(ans,now);
		
	}
	cout<<ans<<endl;

}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cout<<fixed<<setprecision(12);

    int T = 1;//cin>>T;
    while (T--) {
        solve();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值