codeforces 626E. Simple Skewness 三分
给n个数, 让你去掉一些数, 使得剩下的数的平均值-中位数的差值最大。
先将数组排序, 然后枚举每一个数作为中位数的情况, 对于每个枚举的数, 三分它的左右区间长度找到一个平均值最大的情况, 平均值最大, 肯定是它左边的数是靠近他的那几个数, 右边的数是最右边的那几个数。 然后所有情况取最大值。
三分的写法lmid = (l*2+r)/2, rmid = (l+r*2+2)/3, 学到了。
并且求平均值最好不要除,比如说平均数-中位数, 那么写成 这几个数的和-中位数*长度。
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <map> 8 #include <set> 9 #include <string> 10 #include <queue> 11 #include <stack> 12 #include <bitset> 13 using namespace std; 14 #define pb(x) push_back(x) 15 #define ll long long 16 #define mk(x, y) make_pair(x, y) 17 #define lson l, m, rt<<1 18 #define mem(a) memset(a, 0, sizeof(a)) 19 #define rson m+1, r, rt<<1|1 20 #define mem1(a) memset(a, -1, sizeof(a)) 21 #define mem2(a) memset(a, 0x3f, sizeof(a)) 22 #define rep(i, n, a) for(int i = a; i<n; i++) 23 #define fi first 24 #define se second 25 typedef pair<int, int> pll; 26 const double PI = acos(-1.0); 27 const double eps = 1e-8; 28 const int mod = 1e9+7; 29 const int inf = 1061109567; 30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 31 const int maxn = 2e5+5; 32 ll a[maxn], sum[maxn]; 33 int n; 34 ll cal(int len, int pos) { 35 ll num = sum[pos]-sum[pos-len-1]+sum[n]-sum[n-len]; 36 return num; 37 } 38 int main() 39 { 40 cin>>n; 41 for(int i = 1; i<=n; i++) { 42 scanf("%I64d", &a[i]); 43 } 44 if(n == 1 || n == 2) { 45 cout<<1<<endl; 46 cout<<a[1]<<endl; 47 return 0; 48 } 49 sort(a+1, a+1+n); 50 ll maxx = 0; 51 int len = 0, mid = 1; 52 for(int i = 1; i<=n; i++) 53 sum[i] = sum[i-1]+a[i]; 54 for(int i = 2; i<=n-1; i++) { 55 int l = 0, r = min(i-1, n-i); 56 while(l<r) { 57 int lmid = (2*l+r)/3; 58 int rmid = (l+2*r+2)/3; 59 ll ans1 = cal(lmid, i); 60 ll ans2 = cal(rmid, i); 61 if(ans1*(2*rmid+1)<(2*lmid+1)*ans2) { 62 l = lmid+1; 63 } else { 64 r = rmid-1; 65 } 66 } 67 ll tmp = (sum[i]-sum[i-l-1]+sum[n]-sum[n-l])-(2*l+1)*a[i]; 68 if(tmp*(2*len+1)>maxx*(2*l+1)) { 69 maxx = tmp; 70 len = l; 71 mid = i; 72 } 73 } 74 cout<<2*len+1<<endl; 75 for(int i = mid-len; i<=mid; i++) 76 printf("%d ", a[i]); 77 for(int i = n-len+1; i<=n; i++) 78 printf("%d ", a[i]); 79 return 0; 80 }