Frosh Week
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2565 Accepted Submission(s): 851
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
Source
此题从题意上因为要我们求区间和,很容易想到的是用树状数组,本是一道痕水的题,但是由于我们树状数组全是由下标1开始(注意!不是0,如果有0在我们的函数中会出现死循环)的数组,但这题的数据并不是这样的,不过并没有关系,仔细观察你会发现,其实这里的数据并不需要它具体的值,我们需要知道的仅仅是它们相互之间的大小关系,所以我们采取对数据的离散化,以便我们用到树状数组,可能很多童鞋又要问小编数据的离散化是什么意思0.0……数据的离散化在这里说白了,就是按照大小关系重新对数据从1开始进行赋值,只有这样我们才能用我们喜欢(小编假设大家跟小编一样0.0)的树状数组。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define LL __int64
using namespace std;
const int maxn = 1000005;
int a[maxn],n;
struct node
{
int num,id;
}ch[maxn];
int cmp1(node a,node b)
{
return a.num < b.num;
}
int cmp2(node a,node b)
{
return a.id < b.id;
}
int Lowbit(int k)
{
return k&(-k);
}
void update(int k,int x)
{
while(k <= n)
{
a[k] += x;
k += Lowbit(k);
}
}
int getsum(int x)
{
int sum = 0;
while(x > 0)
{
sum += a[x];
x -= Lowbit(x);
}
return sum;
}
int main()
{
int i;
LL ans;
while(scanf("%d",&n)!=EOF)
{
ans = 0;
memset(a,0,sizeof(a));
for(i=1; i<=n; i++)
{
scanf("%d",&ch[i].num);
ch[i].id = i;
}
sort(ch+1,ch+n+1,cmp1);//数据的离散化
ch[1].num = 1;
for(i=2; i<=n; i++)
{
if(ch[i].num != ch[i-1].num)
ch[i].num = i;
else ch[i].num = ch[i-1].num;
}
sort(ch+1,ch+1+n,cmp2);
for(i=1; i<=n; i++)
{
update(ch[i].num,1);
ans += (getsum(n) - getsum(ch[i].num));
}
printf("%I64d\n",ans);
}
return 0;
}
FroshWeek游戏算法解析
本文介绍了一个名为FroshWeek的游戏中的算法问题,该问题是关于如何通过最少的交换次数来将队伍成员按学生编号排序。文章提供了一种使用树状数组结合数据离散化的解决方案,并附带详细的代码实现。
6万+

被折叠的 条评论
为什么被折叠?



