您的位置:首页 > 其它

【noip 2013】火柴排队

2017-08-03 16:06 274 查看
离noip2017还有99天了,开个博客记录一下,不要让自己颓废

题目描述

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度。

每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对99,999,997 取模的结果。

输入格式:

共三行,第一行包含一个整数 n,表示每盒中火柴的数目。 第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。 第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

输出格式:

输出共一行,包含一个整数,表示最少交换次数对 99,999,997 取模的结果。

数据范围:

对于 100%的数据,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ maxlongint

这道题洛谷评为提高+/省选-,我觉得还是略水(虽然我只是一个学了几个月编程的蒟蒻),比起别的题目来说这道题还是比较好想的。

首先,什么状态下火柴距离最小?我第一反应就是如果a列第i高的火柴和b列第i高的火柴一一对应,这时距离应该是最小的。因为我很菜,所以一时半会没想出来证明方法。但按照“两数和相等差越小积越大”这种感觉应该是对的(领会精神….)。

然后,问题就来到了如何用最少的交换次数达到高度排名的一一对应?显然,如果以第一列火柴为标准,那么我们可以只交换第二列火柴达到目的。有一点冒泡排序的味道,而冒泡排序可以…对!求逆序对!如果对第二列火柴进行编号,问题就转化为求第二列火柴高度排名的逆序对的个数,用归并排序就可以解决因为我不会用树状数组求.

问题是,怎样重新编号?思考之后,我发现问题的本质就是要找b列火柴中的哪一根与a列火柴的哪一根在各自队伍中的排名相同,那么就给这两根火柴相同的编号i,i是该火柴在a列火柴中的位置。现在问题就变得明了了,要求排名相同的火柴,我们只需要排序,并开一个结构体记录火柴本来的位置,就解决了问题。

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int ind;
long long h;
}a[100001],b[100001];
int ans=0;
int c[100001];
int tmp[100001];
const int mod=99999997;
bool cmp(node a,node b)
{
return a.h<b.h;
}
long long read()
{
long long x=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
void msort(int l,int r)
{
if(l==r) return ;
int mid=(l+r)/2;
msort(l,mid);
msort(mid+1,r);
int i=l,j=mid+1,k=l;
while(i<=mid&&j<=r)
{
if(c[i]<=c[j]) tmp[k++]=c[i++];
else
{
tmp[k++]=c[j++];
ans+=mid-i+1;
ans%=mod;
}
}
while(i<=mid) tmp[k++]=c[i++];
while(j<=r) tmp[k++]=c[j++];
for(int i=l;i<=r;i++)
c[i]=tmp[i];
}
int main()
{
int n;
n=read();
for(int i=1;i<=n;i++)
{
a[i].h=read();
a[i].ind=i;
}
for(int i=1;i<=n;i++)
{
b[i].h=read();
b[i].ind=i;
}
sort(a+1,a+n+1,cmp);
sort(b+1,b+n+1,cmp);
for(int i=1;i<=n;i++)
c[b[i].ind]=a[i].ind;
msort(1,n);
printf("%d",ans%mod);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: