题意:
给定N≤2×103的两个序列,给定0≤k≤2次交换2个序列中一个数的操作,使得|suma−sumb|最小
分析:
然后尺取法求解,最小值一定在大于0和小于0之间k很小,所以可以枚举,k=0或者k=1直接搞就可以了
对于k=2,我们可以预处理出2个序列的C2n个数
对于交换的2个数ai,bj,a序列suma′=suma−ai+bj,b序列sumb′=sumb+ai−bj
dif′=suma′−sumb′=suma−sumb+2∗(−ai+bj)
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-9
#define maxn 100100
#define MOD 1000000007
int n,m;
long long a[2020],b[2020];
struct node
{
int x,y;
long long val;
bool operator < (const node & a)const
{
return val < a.val;
}
}aa[4000040],bb[4000040];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t,C = 1;
//scanf("%d",&t);
while(scanf("%d",&n) != EOF)
{
long long sum1 = 0,sum2 = 0;
for(int i = 0; i < n; i++)
{
scanf("%lld",&a[i]);
sum1 += a[i];
}
scanf("%d",&m);
for(int i = 0; i < m; i++)
{
scanf("%lld",&b[i]);
sum2 += b[i];
}
long long Min = abs(sum1-sum2);
int ans1 = -1,ans2 = -1;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
{
long long k1 = sum1 - a[i] + b[j];
long long k2 = sum2 - b[j] + a[i];
if(abs(k1-k2) < Min)
{
Min = abs(k1-k2);
ans1 = i+1;
ans2 = j+1;
}
}
int pos1 = 0,pos2 = 0;
for(int i = 0; i < n; i++)
for(int j = i + 1; j < n; j++)
{
aa[pos1].x = i+1;
aa[pos1].y = j+1;
aa[pos1++].val = a[i] + a[j];
}
sort(aa,aa+pos1);
for(int i = 0; i < m; i++)
for(int j = i + 1; j < m; j++)
{
bb[pos2].x = i+1;
bb[pos2].y = j+1;
bb[pos2++].val = b[i] + b[j];
}
sort(bb,bb+pos2);
int index1 = 0,index2 = 0;
long long sum = sum1 - sum2;
int anss1 = -1,anss2 = -1;
while(index1 < pos1 && index2 < pos2)
{
long long cnt = sum - 2 * aa[index1].val + 2 * bb[index2].val;
if(abs(cnt) < Min)
{
Min = abs(cnt);
anss1 = index1;
anss2 = index2;
}
if(cnt < 0)
index2++;
else
index1++;
}
printf("%lld\n",Min);
if(anss1 != -1)
printf("2\n%d %d\n%d %d\n",aa[anss1].x,bb[anss2].x,aa[anss1].y,bb[anss2].y);
else if(ans1 != -1)
printf("1\n%d %d\n",ans1,ans2);
else
printf("0\n");
}
return 0;
}