【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 ...
随机推荐
- HDU 4941 Magical Forest --STL Map应用
题意: 有n*m个格子(n,m <= 2*10^9),有k(k<=10^5)个格子中有值,现在有三种操作,第一种为交换两行,第二种为交换两列,交换时只有两行或两列都有格子有值或都没有格子有 ...
- 线性代数与MATLAB2
已知矩阵 求它们的特征值和特征向量,并绘制特征向量图,分析其几何意义 运行Meigvector.m A1=[-1 3;2 5]; A2=[1 -2;-1 5]; A3=[1 2;2 4]; A4=[2 ...
- javascript发送验证码
一个发送验证码的javascript代码 var T = 0; var handle = null; var event = null; $(function(){ $('#sendCode').cl ...
- 序列化在Netty中的使用
Java序列化的缺点 1.无法跨语言 对于Java序列化后的字节数组,别的语言无法进行反序列化 2.序列化后的码流过大 3.序列化性能低 使用JDK自带的序列化进行对象的传输 被传输的,实现了序列化接 ...
- 【C#】【MySQL】C# 查询数据库语句@Row:=@Row+1
如何实现数据库查询产生虚拟的一列序号的功能: ) )AS r; 该语句可以实现产生虚拟的一列数据在MySQL中运行没有问题. 但是在C#里面调用去出现了错误"Parameter '@ROW' ...
- AS2.0大步更新 Google强势逆天
New Features in Android Studio 2.0Instant Run: Faster Build & Deploy逆天吗?你还在羡慕iOS的playground吗?And ...
- [CareerCup] 14.5 Object Reflection 对象反射
14.5 Explain what object reflection is in Java and why it is useful. Java中的对象反射机制可以获得Java类和对象的反射信息,并 ...
- LeetCode 笔记25 Candy (艰难的调试)
There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...
- 软件工程(GZSD2015)第二次作业文档模板
题目: (此处列出题目) 需求分析: 基本功能 基本功能点1 基本功能点2 ... 扩展功能(可选) 高级功能(可选) 设计 设计点1 设计点2 ... 代码实现 // code here 程序截图 ...
- Spring MVC的工作流程
前端控制器(DispatcherServlet): (不需要我们开发)接收请求,响应结果,相当于转发器,中央处理器.减少了其它组件之间的耦合度. springmvc.xml是SpringMVC的一个全 ...