noip2013 火柴排序

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:

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

intput:

4
2 3 1 4
3 2 1 4

output:

1

思路:

先开一个结构体,然后输入。按照v的大小升序排序。

1 const int maxn=100010;
2 struct cyc
3 {
4     int V,id;
5 }a[maxn],b[maxn];

然后,将a中元素对应b的的位置储存到c。

最后,归并排序即可。

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<iomanip>
 8 #include<queue>
 9 using namespace std;
10 const int maxn=100010,lln=99999997;
11 struct cyc
12 {
13     int v,id;
14 }a[maxn],b[maxn];
15 int n;
16 int c[maxn],d[maxn];
17 int ans=0;
18 bool myc(cyc x,cyc y)
19 {
20     return x.v<y.v;
21 }
22 void work(int l,int r)
23 {
24     int mid,tmp,i,j;
25     if(l+1<r)
26     {
27         mid=(l+r)/2;
28         work(l,mid-1);
29         work(mid,r);
30         tmp=l;
31         for(i=l,j=mid;i<=mid-1&&j<=r;)
32         {
33             if(c[i]>c[j])
34             {
35                 d[tmp++]=c[j++];
36                 ans=1LL*(ans+mid-i)%lln;
37             }
38             else
39             {
40                 d[tmp++]=c[i++];
41             }
42         }
43         if(j<=r)
44         {
45             for(;j<=r;j++)    d[tmp++]=c[j];
46         }
47         else
48         {
49             for(;i<=mid-1;i++)    d[tmp++]=c[i];
50         }
51         for(i=l;i<=r;i++)
52             c[i]=d[i];
53     }
54     else{
55         if(l+1==r)
56         {
57             if(c[l]>c[r])
58             {
59                 swap(c[l],c[r]);
60                 ans=1LL*(ans+1)%lln;
61             }
62         }
63     }
64 }
65 int main()
66 {
67     /*freopen("2.in","r",stdin);
68     freopen("2.out","w",stdout);*/
69     //ios::sync_with_stdio(false);
70     cin>>n;
71     for(int i=1;i<=n;i++)
72     {
73         cin>>a[i].v;
74         a[i].id=i;
75     }
76     for(int i=1;i<=n;i++)
77     {
78         cin>>b[i].v;
79         b[i].id=i;
80     }
81     sort(a+1,a+1+n,myc);
82     sort(b+1,b+1+n,myc);
83     for(int i=1;i<=n;i++)
84         c[b[i].id]=a[i].id;
85     work(1,n);
86     cout<<ans<<endl;
87     return 0;
88 }

时间: 2024-09-30 09:20:03

noip2013 火柴排序的相关文章

noip2013火柴排队_Solution

要想对任意(ai,bi)和(aj-和b-j),当ai<aj时,都有bi<=bj:当ai>=aj时,bi>=bj,当对a进行升序排序后(b同时发生改变,从而不改变值,最后有a1<=a2<=-<=an),必须满足b1<=b2<=-<=b-n. 否则,必存在(ai,bi)和(aj-和b-j),有ai<aj且bi>bj,交换ai和aj后,(aj*bi+ ai*bj)-( ai*bi+ aj*bj)=(aj-ai)*( bi-bj)>0,

NOIP2013 火柴排队

逆序对的经典题目.考试的时候不知道怎么写丑了,全WA了,正好带我复习了一遍逆序对. 将火柴序列从小到大分配一个等级,当a的等级与对应的b的等级相同时,答案最小,至于为什么是这样,我就不证明了.这里的等级,实际上就是离散化. 把a的等级从小到大排序之后,再把b对应a的等级排序,求出现在b的等级序列中的逆序对,就是我们要求的交换次数,因为每交换一次,只能使一组逆序对变成有序的. 注意暴搜求逆序对是要超时的,只能得70分,因此用树状数组求和才能过. #include<iostream> #inclu

jzoj[1438]NOIP2013火柴排队

读题: 相邻两个火柴可以交换?两个火柴序列?嗅到了归并排序的味道. 读完题目之后,我们可以知道,如果想要交换次数最少,可以先固定一个序列不变,比如说a序列不变,变b序列 样例是 4 2 3 1 4 3 2 1 4 则给他们编过号码之后,a序列也就是这样: a 2 b 3 c 1 d 4 按从小到大排序也就有 c 1 a 2 b 3 d 4 这样就把b组序列的顺序搞出来了, 然后结合归并排序求解逆序对即可

NOIp2013火柴排队

题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度. 每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小.请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果. 输入输出格式 输

水题 逆序对 NOIP 2013 火柴排队

题目如下 题目描述 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:,其中 ai表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度.每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小.请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果. 输入描述 Inp

9-15考试题目程序作业

然而有素质的我选择把题目也粘在上面,喜欢的同学可以做一下 支付宝(pay.pas/c/cpp)题目描述做完前七次Nescafé 模拟赛之后,你已经欠了一大笔电费.现在收电费的已经把你堵在了家里.当然了,你并不是打算一直拖欠电费的人,你只是如果不能用最少的纸币张数凑出电费金额的话会感到十分不爽.本来这是一件很简单的事,但是你平常很少使用标准的纸币,而是习惯去银行领一本支票簿,在每一张上填上自己喜欢的金额然后把这些东西用作纸币付账,这就使问题变得复杂了起来.现在你知道你一共填写了N种金额的支票,第i

求排列的逆序数(9018_1679)

为了做noip2013的火柴排序,特地练了一下逆序对的求法. 逆序对的求法,若要nlogn,有2种,一种就是用归并排序的思想.另一种,就是线段树或者树状数组. 这里,我采用了第一种. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getc

NOIP试题解析

NOIP试题解析           by QTY_YTQ noip2010关押罪犯(并查集) 题意是有n个罪犯关在两个监狱中,其中有m对罪犯有仇恨关系,如果有仇恨的罪犯关在一起会产生一定影响力的事件,要求安排罪犯位置使产生影响力最大的事件影响最小. 可以用并查集来做,每个罪犯抽象为两个点,一个表示该罪犯关押在1监狱,另一个表示该罪犯关押在2监狱,我们将罪犯仇恨关系按影响的大小排序,每次选取影响力最大的一对罪犯(x,y),尽可能不让它们在一个监狱内,将x1和y2合并,将x2和y1合并,继续往后做

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734