Mali 水题
给定N组数字,要求对当前给定的一串数字进行一次错排,在这些错排中有一组最大值,求这组最大值的最小的错排方式。一般的写法是左边的序列从小到大进行排序,右边从大到小进行排序,然后进行组合,这样的一组排列时最优的排列。因为任意交换这样一个序列的元素相对位置必定会使得配对值不平均。但是如果简简单单是这样来做的话肯定是会超时的,我们就注意到左边和右边的值是1-100之间的值,因此我们用一个数组来记录1-100的个数即可,这样就不用每次来排序并且一一计算了。
代码如下:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #define INF 0x7fffffff using namespace std; int N, L[105], R[105], ll[105], rr[105]; void deal() { int ret = -INF; int i = 1, j = 100; memcpy(ll, L, sizeof (L)); memcpy(rr, R, sizeof (R)); for (; i <= 100 && j >= 1;) { if (ll[i] == 0) ++i; else if (rr[j] == 0) --j; else if (ll[i] >= rr[j]) { ll[i] -= rr[j]; ret = max(ret, i + j); --j; } else { rr[j] -= ll[i]; ret = max(ret, i + j); ++i; } } printf("%d\n", ret); } int main() { int a, b; while (scanf("%d", &N) == 1) { memset(L, 0, sizeof (L)); memset(R, 0, sizeof (R)); for (int i = 1; i <= N; ++i) { scanf("%d %d", &a, &b); ++L[a], ++R[b]; //左边多了a,右边多了b deal(); } } return 0; }