题意

两个数列,一个有n个数,另一个有m个数,让你最多交换两次两个数列的数,使得两个数列和的差的绝对值最小,求这个差的绝对值、最少交换次数、交换数对

分析

交换0次、1次可得到的最小的差可以枚举出来。

交换两次,如果枚举就超时了。

我们预处理把第一个数列两两组合的所有情况存储起来为u数组,并且按照大小排序,接着在另一个数列里枚举两个数后,用二分的方法,求交换后使得 差的绝对值最小 的u。

二分查找最接近的值可以用lower_bound函数。

代码

#include<stdio.h>
#include<cmath>
#include<map>
#include<utility>
#define N 2005
#define ll long long using namespace std;
ll a[N],b[N],n,m,suma,sumb,v,ans,c; map<ll,pair<int,int> >u;
map<ll,pair<int,int> >::iterator it;
pair<int,int>swap1,swap2; void update(int i,int j)
{
if(abs(c-it->first) < v)
{
ans=;
v = abs(c - it->first);
swap1 = it->second;
swap2 = {i,j};
}
} int main()
{
scanf("%lld",&n);
for(int i=; i<=n; i++)
{
scanf("%lld",&a[i]);
suma+=a[i];
} scanf("%lld",&m);
for(int i=; i<=m; i++)
{
scanf("%lld",&b[i]);
sumb+=b[i];
} v=abs(suma-sumb);
if(!v)
{
printf("0\n0\n");
return ;
} for(int i=; i<n; i++)
for(int j=i+; j<=n; j++)
u[(a[i]+a[j])*2LL] = {i,j}; for(int i=; i<=n; i++)
for(int j=; j<=m; j++)
if(abs(suma-sumb-2LL*(a[i]-b[j]))<v)
{
ans=;
v=abs(suma-sumb-2LL*(a[i]-b[j]));
swap1= {i,j};
}
for(int i=; i<m; i++)
for(int j=i+; j<=m; j++)
{
c=suma-sumb+2LL*(b[i]+b[j]);
it=u.lower_bound(c);
if( it != u.end() )
update(i,j);
if( it != u.begin() )
{
it--;
update(i,j);
}
} printf("%lld\n%lld\n",v,ans); if(ans==)printf("%d %d\n",swap1.first,swap1.second);
if(ans==)printf("%d %d\n%d %d\n",swap1.first,swap2.first,swap1.second,swap2.second); return ;
}

2017.7.21 ps. 今天再做这题,wa了八下。因为自己写的二分,一开始忘记考虑n==1的情况(这样就不存在a数组里选两个加起来了,二分的结果没有意义)。之后发现我二分查找的是加了绝对值的,显然不需要加绝对值。以及如果二分查找的值不存在,那么得到的就是大于它的第一个值,所以还要考虑小于它的第一个值。最终AC的代码如下:

#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
#define N 2001
int n,m,a[N],b[N];
struct Node{
ll a,b,v;
}sum[N*N];
ll sa,sb;
int x[],y[];
int cnt;
ll ans;
bool cmp(const Node& a,const Node& b){
return a.v<b.v;
}
int bs(ll s){
int l=,r=cnt;
while(l<r){
int mid=l+r>>;
if(sum[mid].v<s)
l=mid+;
else
r=mid;
}
return l;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;++i)
scanf("%d",a+i),sa+=a[i];
scanf("%d",&m);
for(int i=;i<=m;++i)
scanf("%d",b+i),sb+=b[i]; for(int i=;i<n;++i)
for(int j=i+;j<=n;++j)
sum[++cnt]=(Node){i,j,2LL*(a[i]+a[j])}; ans=abs(sb-sa); sort(sum+,sum++cnt,cmp);
int k=; for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
ll t=abs(sa-a[i]*-sb+b[j]*);
if(t<ans){
ans=t;
k=;
x[]=i;y[]=j;
}
}
if(cnt){
for(int i=;i<m;++i)
for(int j=i+;j<=m;++j){
ll t=sa-sb+2LL*(b[i]+b[j]);
int d=bs(t);
for(int g=-;g<;++g)if(d+g>&&d+g<=cnt){
ll tans=abs(t-sum[d+g].v);
if(tans<ans){
ans=tans;
k=;
x[]=sum[d+g].a;y[]=i;
x[]=sum[d+g].b;y[]=j;
}
}
}
}
printf("%lld\n%d\n", ans,k);
for(int i=;i<k;++i)
printf("%d %d\n",x[i],y[i]);
return ;
}

【CodeForces 620D】Professor GukiZ and Two Arrays的更多相关文章

  1. CodeForces 620D Professor GukiZ and Two Arrays 双指针

    Professor GukiZ and Two Arrays 题解: 将a数组都sort一遍之后, b数组也sort一遍之后. 可以观察得到 对于每一个ai来说, 整个数组bi是一个V型的. 并且对于 ...

  2. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  3. Educational Codeforces Round 6 D. Professor GukiZ and Two Arrays 二分

    D. Professor GukiZ and Two Arrays 题目连接: http://www.codeforces.com/contest/620/problem/D Description ...

  4. Educational Codeforces Round 6 D. Professor GukiZ and Two Arrays

    Professor GukiZ and Two Arrays 题意:两个长度在2000的-1e9~1e9的两个序列a,b(无序);要你最多两次交换元素,使得交换元素后两序列和的差值的绝对值最小:输出这 ...

  5. 【24.67%】【codeforces 551C】 GukiZ hates Boxes

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. 【74.89%】【codeforces 551A】GukiZ and Contest

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. 【19.46%】【codeforces 551B】ZgukistringZ

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. 【codeforces 757B】 Bash's Big Day

    time limit per test2 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...

  9. 【codeforces 707E】Garlands

    [题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...

随机推荐

  1. hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)

    题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: ...

  2. AC日记——codevs 1688 求逆序对

    1688 求逆序对  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 给定一个序列a1,a2,…, ...

  3. github结合TortoiseGit使用sshkey,无需输入账号和密码

    1.github上支持三种方式进行项目的clone    https,ssh,subversion https://github.com/用户名/版本库.git ssh的方式 git@github.c ...

  4. [ORACLE错误]ORA-00001: unique constraint (...) violated并不一定是数据冲突

    遇到这种情况,重建完表和索引后,终于正常INSERT了.  prompt Importing table COUPON_ACTIVITYset feedback offset define offin ...

  5. smarty缓存控制

    第一步初始化配置文件中设置 如果当前访问的模板有缓存就不需要连接数据库那些代码了,如果要模板局部不缓存,要写在iscache外,模板中用{nocache}

  6. 1445 送Q币

    1445 送Q币  时间限制: 1 s  空间限制: 1000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 一次在玩网络游戏的过程中,在 ...

  7. VisualStudio2013+EF6+MySql5.5环境下配置

    看院子里对EF框架和MySql的配置文章不少,但是几乎出自一篇文章的转载,而且这篇转载的文章的也比较坑爹,下面我将介绍一下我的配置过程: 第一步:安装mysql-connector-net-6.9.9 ...

  8. 谷歌验证 (Google Authenticator) 的实现原理是什么?

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:徐小花链接:http://www.zhihu.com/question/20462696/answer/18731073来源: ...

  9. [iOS翻译]Cocoa编码规范

        简介: 本文整理自Apple文档<Coding Guidelines for Cocoa>.这份文档原意是给Cocoa框架.插件及公共API开发者提供一些编码指导,实质上相当于Ap ...

  10. Navicat创建和设计MySQL事件

    1.开启定时器 0:off 1:on SET GLOBAL event_scheduler = 1; 2.在navicat左侧选择一个数据库,单击“时间”-“创建事件”,弹出一个窗口.