题目大意:给定 n 个三元组 (x,y,z),让你选出 m 个三元组,使得得分最大。一种选法的得分是 ∣∑x∣+∣∑y∣+∣∑z∣,比如 (1,2,3),(−1,2,−9) 的得分是 ∣1+(−1)∣+∣2+2∣+∣3+(−9)∣=10
数据范围:n≤1000,−1010≤x,y,z≤1010
本人的想法是给每个三元组一个权值 s=ax+by+cz,其中 a,b,c=±1,按照权值排序选前 m 个,最后把八种情况的得分取 max 就是答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template <typename T>
inline void read(T &x){x=0;char ch=getchar();bool f=0;while(ch<'0'||ch>'9'){if(ch == '-')f = 1;ch = getchar();}while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();if(f)x=-x;}
template <typename T,typename ...Args>
inline void read(T &tmp,Args &...tmps){read(tmp);read(tmps...);}
inline void readn(int a[],int _){for(int i=1;i<=_;i++) read(a[i]);}
constexpr int N=1002;
struct node
{
int x,y,z;
}g[N];
int n,m;
inline ll solve(int a,int b,int c)
{
sort(g+1,g+n+1,[&](node x,node y){
ll s1=x.x*a+x.y*b+x.z*c;
ll s2=y.x*a+y.y*b+y.z*c;
return s1<s2;
});
ll s1=0,s2=0,s3=0;
for(int i=1;i<=m;i++)
{
s1+=g[i].x;
s2+=g[i].y;
s3+=g[i].z;
}
return abs(s1)+abs(s2)+abs(s3);
}
int main()
{
read(n,m);
for(int i=1;i<=n;i++) read(g[i].x,g[i].y,g[i].z);
ll ans=-1ll<<60;
for(int i=-1;i<=1;i+=2)
for(int j=-1;j<=1;j+=2)
for(int k=-1;k<=1;k+=2)
ans=max(ans,solve(i,j,k));
printf("%lld",ans);
return 0;
}
这个点 WA 了,输入数据 答案输出 8923332648559 (数据太大只能放这了)