Problem Description
During Frosh Week, students play various fun games to get to know each other and compete against other teams. In one such game, all the frosh on a team stand in a line, and are then asked to arrange themselves according to some criterion, such as their height, their birth date, or their student number. This rearrangement of the line must be accomplished only by successively swapping pairs of consecutive students. The team that finishes fastest wins. Thus, in order to win, you would like to minimize the number of swaps required.
 
Input
The first line of input contains one positive integer n, the number of students on the team, which will be no more than one million. The following n lines each contain one integer, the student number of each student on the team. No student number will appear more than once. 
 
Output
Output a line containing the minimum number of swaps required to arrange the students in increasing order by student number. 
 
Sample Input
3 3 1 2
 
Sample Output
2
 
分析题意后发现是一个求逆序数的问题
给一列数A[1],A[2],…,A[n],求它的逆序数,即有多少个有序对(i,j),使得i<j但A[i]>A[j]。
受归并排序启发,用分治法解决该问题,把序列分成元素个数尽量相等的两半,递归统计i和j均在左边或者均在右边的逆序数,再统计i在左边,但j在右边的逆序数。
对于i在左边,j在右边的分类,按照j的不同把这些“跨越两边”的逆序对进行分类,只要对于右边的每个j,统计左边比它大的元素个数cnt,则所有cnt之和便是答案。归并排序时,当右边的A[j]复制到辅助数组ass中时,左边还没来得及复制到ass的那些数就是左边所有比A[j]大的数。此时cnt加上左边元素个数mid-p即可(左边所剩的元素在区间[p,mid)中,因此元素个数为mid-p)。
 
归并排序:
(1)划分问题:把序列分成元素个数尽量相等的两半。
(2)递归求解:把两半元素分别进行归并排序。
(3)合并问题:把两个有序表合并成一个。合并时每次只需要把两个序列的最小元素加以比较,删除其中的较小元素并加入合并后的新表即可。
 
注意小细节
(1)代码中使用的左闭右开区间,用左闭右开区间来表示一个范围,好处是在处理“数组分割”时比较自然,区间[low,high)被分成的是[low,mid)和[mid,high),不需要在任何地方加减1(主函数中调用时high要赋上n+1),另外,空区间表示为[x,x),比[x,x-1]顺眼多了。
(2)分界点mid=low+(high-low)/2而不是(low+high)/2,数学上两者相等,但在计算机中却有差别,运算符“/”的取整是朝零方向的取整,用low+(high-low)/2来确保分界点总是靠近区间起点(虽然在这题中并非必要),还有一点,使用mid=low+(high-low)/2还可以避免low+high在low和high很大时可能会出现的溢出。
(3)/2用>>1实现
 #include <stdio.h>
#define MAX 1000000 int arr[MAX+],ass[MAX+];
__int64 cnt; void MergeSort(int low,int high){
int mid,p,q,i;
if(high-low==)
return;
mid=low+((high-low)>>);
MergeSort(low,mid);
MergeSort(mid,high);
p=low,q=mid,i=low;
while(p<mid||q<high){
if(q>=high||(p<mid&&arr[p]<=arr[q]))
ass[i++]=arr[p++];
else{
ass[i++]=arr[q++];
cnt+=mid-p;
}
}
for(i=low;i<high;i++)
arr[i]=ass[i];
} void scani(int &num){
char ch;
int flag;
while(ch=getchar(),(ch>''||ch<'')&&(ch!='-'));
if(ch=='-')
flag=-,num=;
else
flag=,num=ch-'';
while(ch=getchar(),ch<=''&&ch>='')
num=num*+ch-'';
num*=flag;
} int main(){
int n,i;
while(~scanf("%d",&n)){
for(i=;i<=n;i++)
scani(arr[i]);
cnt=;
MergeSort(,n+);
printf("%I64d\n",cnt);
}
return ;
}

Frosh Week的更多相关文章

  1. HDU 3743 Frosh Week (线段树+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 Frosh Week Time Limit : 2000/1000ms (Java/Other) ...

  2. UVA 11858 Frosh Week 逆序对统计

    题目链接: http://acm.hust.edu.cn/vjudge/contest/122094#problem/H Frosh Week Time Limit:8000MSMemory Limi ...

  3. 暑假集训(2)第六弹 ----- Frosh Week(UVA11858)

    H - Frosh Week Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     ...

  4. 问题 C: Frosh Week(2018组队训练赛第十五场)(签到)

    问题 C: Frosh Week 时间限制: 4 Sec  内存限制: 128 MB提交: 145  解决: 63[提交][状态][讨论版][命题人:admin] 题目描述 Professor Zac ...

  5. Frosh Week(归并排序求逆序数)

    H - Frosh Week Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Desc ...

  6. HDU 3743 Frosh Week(归并排序求逆序对)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 题目意思就是给你一个长为n的序列,让你求逆序对.我用的是归并排序来求的.归并排序有一个合并的过程 ...

  7. HDU 3743 Frosh Week(归并排序求逆序数)

    归并排序求逆序数 #include <iostream> #include <cstdio> using namespace std; #define maxn 1000005 ...

  8. Frosh Week HDU3743(逆序数)

    离散化加 求逆序数: 求逆序数的方法 一个是归并排序  一个是树状数组 #include<bits/stdc++.h> using namespace std; int n; struct ...

  9. Prerequisites?[HDU1144]

    Prerequisites?Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...

随机推荐

  1. exeption ORA-00907: missing right parenthesis

      exeption ORA-00907: missing right parenthesis CreationTime--2018年8月16日11点11分 Author:Marydon 1.情景展示 ...

  2. Tomcat SSL配置 Connector attribute SSLCertificateFile must be defined when using SSL with APR解决

    原文地址:http://blog.csdn.net/kissliux/article/details/17392003 Tomcat 6版本配置SSL过程有两步: 1.用JDK自带的keytool.e ...

  3. 利用SynchronizationContext.Current在线程间同步上下文

    简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色.另外这里有个地方需要清楚的,不是每个线程都附加SynchronizationCon ...

  4. 域名无法解析 Linux临时或永久修改DNS

    最近给VPS重装了系统,因为服务商不提供DHCP,所以只好手动设置IP和DNS Server.悲催的是系统重装的时候忘记了输入DNS Server,最后导致进去系统后,各种域名无法解析. Linux中 ...

  5. cocos2dx 3.2 解决输入框(TextField,TextFieldTTF) 中文乱码问题

    近期开发cocos2dx 项目,做一个小游戏.(个人喜欢用最新版本号) 没系统学习就是问题多多,遇到了非常多问题,比方全部的opengl api都必须在主线程中调用, 这让我在多线程载入方面吃了不少亏 ...

  6. PHP中的一些新特性

    PHP 5.6 1.可以使用表达式定义常量 https://php.net/manual/zh/migration56.new-features.php 在之前的 PHP 版本中,必须使用静态值来定义 ...

  7. nyoj------------找球号(一)

    找球号(一) 时间限制:3000 ms  |           内存限制:65535 KB 难度:3   描述 在某一国度里流行着一种游戏.游戏规则为:在一堆球中,每个球上都有一个整数编号i(0&l ...

  8. 超酷的Android 侧滑(双向滑动菜单)效果

    下面看看我们如何使用它,达到我们想要的效果 public class MainActivity extends Activity { /** * 双向滑动菜单布局 */ private SliderM ...

  9. MySQL 获取某一个分类ID的所有父或子分类查询结果

    创建一个自定义函数: ; DELIMITER $$ USE `dressv_website`$$ DROP FUNCTION IF EXISTS `fn_QueryRelation`$$ CREATE ...

  10. WinDBG 常用命令表[转]

    启动, 附加进程, 执行和退出(Starting, Attaching, Executing and Exiting) =======================   Start -> Al ...