【CodeForces 620D】Professor GukiZ and Two Arrays
题意
两个数列,一个有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的更多相关文章
- CodeForces 620D Professor GukiZ and Two Arrays 双指针
Professor GukiZ and Two Arrays 题解: 将a数组都sort一遍之后, b数组也sort一遍之后. 可以观察得到 对于每一个ai来说, 整个数组bi是一个V型的. 并且对于 ...
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 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 ...
- Educational Codeforces Round 6 D. Professor GukiZ and Two Arrays
Professor GukiZ and Two Arrays 题意:两个长度在2000的-1e9~1e9的两个序列a,b(无序);要你最多两次交换元素,使得交换元素后两序列和的差值的绝对值最小:输出这 ...
- 【24.67%】【codeforces 551C】 GukiZ hates Boxes
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【74.89%】【codeforces 551A】GukiZ and Contest
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【19.46%】【codeforces 551B】ZgukistringZ
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 757B】 Bash's Big Day
time limit per test2 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
随机推荐
- 实习小记-python 内置函数__eq__函数引发的探索
乱写__eq__会发生啥?请看代码.. >>> class A: ... def __eq__(self, other): # 不论发生什么,只要有==做比较,就返回True ... ...
- [cb]Unity 项目架构
一.技能机制 二.游戏工程 三.客户端架构
- Mecanim 学习概述
前言 我要逐个击破Unity中的知识点,包括1.Mecanim 2.NavMesh 3.4.3之后新的GUI系统 4.新的2D功能 5.Shader 6.性能及后期处理 早在2013年初的时候就听说过 ...
- UITextView限制字数与行数
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSSt ...
- SQL 第一范式、第二范式、第三范式、BCNF
作者 : Dolphin 原文地址: http://blog.csdn.net/qingdujun/article/details/27365979 一.第一范式 1NF 要求:每一个分量必须是不可分 ...
- javascript中的后退和刷新
<input type=button value=刷新 onclick="window.location.reload()"><input type=button ...
- SQL2008安装后激活方式以及提示评估期已过解决方法(转)
第一步:进入SQL2008配置工具中的安装中心第二步:再进入维护界面,选择版本升级第三步:进入产品密钥,输入密钥第四步:一直点下一步,直到升级完毕.SQL Server 2008 Developer: ...
- 通过jekyll建立静态网页
部署一个网站需要三个步骤:(1) generating the site, (2) deploying it to the public Internet, and (3) assigning it ...
- qrcodeJS生成二维码
后续抽时间自己来整理笔记 http://code.ciaoca.com/javascript/qrcode/
- 深入分析 Javascript 单线程
面试的时候发现99%的童鞋不理解为什么JavaScript是单线程的却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的?还有non-blocking IO, event l ...