CodeForces 620 D.Professor GukiZ and Two Arrays(枚举+set)

来源:互联网 发布:cms 开源 编辑:程序博客网 时间:2024/05/24 07:29

Description
给出一个长度为n的序列a和一个长度为m的序列b,两个序列的差值定义为序列和做差的绝对值,一次操作可以交换a序列和b序列中一元素,问最多两次交换后两个序列差的最小值
Input
第一行输入一整数n表示a序列长度,之后n个整数a[i]表示a序列,然后输入一整数m表示b序列长度,最后m个整数b[i]表示b序列(1<=n,m<=2000,-1e9<=a[i],b[i]<=1e9)
Output
输出至多两次交换后两个序列差的最小值,然后输出交换的次数以及交换的对象
Sample Input
5
5 4 3 2 1
4
1 1 1 1
Sample Output
1
2
1 1
4 2
Solution
不交换和交换一次的情况直接枚举即可,对于交换两次的情况,设a序列和为sa,b序列和为sb,枚举b序列要交换的两个值b[i]和b[j],那么要在a序列中找两个数x和y,交换后差值为abs(sa-sb+b[i]+b[j]-x-y),x和y的选择有两种,一种是使得sa-sb+b[i]+b[j]负值最大,另一种是正值最小,故用set维护a中任意两个元素组成的和及其编号,每次在set里二分搜索到第一个不小于sa-sb+b[i]+b[j]的值更新下答案(负值最大),再找这个值在set中的前一个更新下答案(正值最小),时间复杂度O(n^2logn)
Code

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 2222int n,m,a[maxn],b[maxn];typedef pair<ll,int>P;vector<P>v;vector<P>::iterator it; int num,a1,a2,b1,b2;int main(){    while(~scanf("%d",&n))    {        ll sa=0,sb=0;        for(int i=1;i<=n;i++)scanf("%d",&a[i]),sa+=a[i];        scanf("%d",&m);        for(int i=1;i<=m;i++)scanf("%d",&b[i]),sb+=b[i];        v.clear();        for(int i=1;i<=n;i++)            for(int j=i+1;j<=n;j++)                v.push_back(P(2ll*(a[i]+a[j]),i*(n+1)+j));        sort(v.begin(),v.end());        num=0;        ll ans=abs(sa-sb);        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++)                if(abs(sa-sb-2ll*(a[i]-b[j]))<ans)                {                    ans=abs(sa-sb-2ll*(a[i]-b[j]));                    num=1,a1=i,b1=j;                }        for(int i=1;i<=m;i++)            for(int j=i+1;j<=m;j++)            {                ll temp=sa-sb+2ll*(b[i]+b[j]);                it=lower_bound(v.begin(),v.end(),P(temp,0));                if(it!=v.end())                {                    if(ans>abs(temp-it->first))                    {                        ans=abs(temp-it->first),num=2;                        a1=it->second/(n+1),a2=it->second%(n+1);                        b1=i,b2=j;                    }                }                if(it!=v.begin())                {                    it--;                    if(ans>abs(temp-(it->first)))                    {                        ans=abs(temp-(it->first)),num=2;                        a1=it->second/(n+1),a2=it->second%(n+1);                        b1=i,b2=j;                    }                }            }        printf("%I64d\n",ans);        printf("%d\n",num);        if(num==1)printf("%d %d\n",a1,b1);        else if(num==2)printf("%d %d\n%d %d\n",a1,b1,a2,b2);    }    return 0;}
0 0
原创粉丝点击