一、题目
二、解法
由于 k ≤ 2 k\leq2 k≤2,那么可以分类讨论, 0 0 0可以直接算, 1 1 1可以暴力枚举。
对于 2 2 2,我们可以把两个绑在一起交换,可以预处理出 B B B所有的组合,枚举 A A A,可以 lower_bound \text {lower\_bound} lower_bound找出对他最优的 B B B(前后都考虑),设 A A A和 B B B的差值为 x x x, A A A的枚举值为 y y y,那么找的值应该是最接近 t − x / 2 t-x/2 t−x/2的。
#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
#define int long long
const int M = 2005;
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,sa,sb,ans,tp,c[4],a[M],b[M];
struct node
{
int v,x,y;
bool operator < (const node &b) const
{
if(v==b.v && x==b.x) return y<b.y;
if(v==b.v) return x<b.x;
return v<b.v;
}
};set<node> s;
int Abs(int x)
{
return x>0?x:-x;
}
signed main()
{
n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
sa+=a[i];
}
m=read();
for(int i=1;i<=m;i++)
{
b[i]=read();
sb+=b[i];
}
ans=Abs(sa-sb);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
sa+=(b[j]-a[i]);
sb+=(a[i]-b[j]);
if(Abs(sa-sb)<ans)
{
ans=Abs(sa-sb);
tp=1;c[0]=i;c[1]=j;
}
sa-=(b[j]-a[i]);
sb-=(a[i]-b[j]);
}
for(int i=1;i<=m;i++)
for(int j=i+1;j<=m;j++)
s.insert(node{b[i]+b[j],i,j});
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(s.empty()) continue;
int x=sa-sb,y=a[i]+a[j];
set<node>::iterator it=s.lower_bound(node{y-x/2,0,0});
if(it==s.end()) it--;
int t=Abs(sa+2*((*it).v)-sb-2*y);
if(t<ans)
{
ans=t;tp=2;
c[0]=i;c[1]=(*it).x;
c[2]=j;c[3]=(*it).y;
}
if(it!=s.begin()) it--;
t=Abs(sa+2*((*it).v)-sb-2*y);
if(t<ans)
{
ans=t;tp=2;
c[0]=i;c[1]=(*it).x;
c[2]=j;c[3]=(*it).y;
}
}
printf("%lld\n%lld\n",ans,tp);
if(tp==1) printf("%lld %lld\n",c[0],c[1]);
if(tp==2) printf("%lld %lld\n%lld %lld\n",c[0],c[1],c[2],c[3]);
}