按照我们蒟蒻菜队的核心思想(排序贪心)来搞这个题,首先想到暴力的方法,然后不用说肯定会TLE。。
然后加一波玄学排序,标准就是 武器点数+Σ|(主武器的属性值-副武器相应属性的平均值)|,这样第一个不总是正解,
因为可能会有这样的情况
2 2 1
0 233
0 346
0 123
0 456
主武器最大值和最小和平均值比较偏离情况是一样的,既然正解不出现在第一对,那第二对如何?第三对如何?
然后
#define prec 1000 //设置精确度,准备在WA与TLE间找到AC
交上去一发就过了。。。
就过了。。。
#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <set>
using namespace std;
#define N 100005
typedef long long ll;
struct wep{
ll S;
ll X[5];
};
wep Main[N],Sec[N];
ll Msum[5],Ssum[N];
int n,m,k;
bool cmpm(const wep&X,const wep&x){
ll sum1 = 0,sum2 = 0;
for(int i = 0 ; i < k ; ++i){
sum1+=abs(m*X.X[i]-Ssum[i]);
sum2+=abs(m*x.X[i]-Ssum[i]);
}
return sum1+m*X.S>sum2+m*x.S;
}
bool cmps(const wep&X,const wep&x){
ll sum1 = 0,sum2 = 0;
for(int i = 0 ; i < k ; ++i){
sum1+=abs(n*X.X[i]-Msum[i]);
sum2+=abs(n*x.X[i]-Msum[i]);
}
return sum1+n*X.S>sum2+n*x.S;
}
#define prec 1000
int main(){
int T;
cin>>T;
while (T--){
cin>>n>>m>>k;
memset(Msum,0, sizeof(Msum));
fill(Ssum,Ssum+5,0);
for(int i = 0 ; i < n ; ++i){
scanf("%lld",&Main[i].S);
for(int j = 0 ; j < k ; ++j){
scanf("%lld",&Main[i].X[j]);
Msum[j]+=Main[i].X[j];
}
}
for(int i = 0 ; i < m ; ++i){
scanf("%lld",&Sec[i].S);
for(int j = 0 ; j < k ; ++j){
scanf("%lld",&Sec[i].X[j]);
Ssum[j]+=Sec[i].X[j];
}
}
sort(Main,Main+n,cmpm);
sort(Sec,Sec+m,cmps);
ll res = Main[0].S+Sec[0].S;
for(int i = 0; i < k ;++i){
res+=abs(Main[0].X[i] - Sec[0].X[i]);
}
ll cur;
int nn = min(prec,n);
int mm = min(prec,m);
for(int i = 0 ; i < nn ; ++i){
for(int j = 0 ; j < mm ; ++j){
cur = Main[i].S+Sec[j].S;
for(int ii = 0; ii < k ;++ii){
cur+=abs(Main[i].X[ii] - Sec[j].X[ii]);
}
res = res>cur?res:cur;
}
}
printf("%lld\n",res);
}
}
算法的正确程度和数据强度成反比。
天天写玄学WA/TLE算法。。