题目链接
有N个飞船进行比赛,它们的跑道为直线并互相平行。每个飞船的起跑位置均不相同。第i个飞船从起跑线右边Xi处开始向右行驶(Xi各不相同)。比赛开始后,它能在零时间内加速到最大速度Vi并永远保持此速度。比赛没有终点,即会永远进行下去。
你的任务是算出比赛过程中一共有多少次"超车"。
自己想法
1.就是求逆序对的个数,用归并排序写的,按理说是对的,可是一直WA。
2.题目明确说速度不会超过100,用计数排序的思想,记录到每个速度的频度。每次输入一个速度,计算目前比他大的速度 的数量,也是计算逆序数对的个数
代码
计数排序代码(AC)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod = 1000000;
int main()
{
int n, v[110];
while(scanf("%d", &n)!=EOF && n){
for(int i = 0; i < 110; i++)
v[i] = 0; //用数组v记录每个速度车的数量,下标i代表速度v
int sum = 0;
while(n--){
int x, vv;
scanf("%d %d", &x, &vv);
v[vv]++; //记录拥有这个速度车的个数
for(int i = vv+1; i < 110; i++){
sum+=v[i];
sum%=mod; //每次加完都要取模,这样避免数据过大
}
}
printf("%d\n", sum);
}
return 0;
}
归并排序代码(WA)
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=250000+4;
const int inf=10000;
int a;
int b;
int x[maxn];
int L[maxn];
int R[maxn];
int n;
int cnt;
void mergy(int p,int q,int r);
void merge_sort(int p,int r)
{
int q;
if(p<r)
{
q=(p+r)>>1;
merge_sort(p,q);
merge_sort(q+1,r);
mergy(p,q,r);
}
}
void mergy(int p,int q,int r)
{
int n1=q-p+1;
int n2=r-q;
int i;
int j;
for(i=1; i<=n1; i++)
{
L[i]=x[p+i-1];
//cout<<L[i]<<" ";
}
//cout<<endl;
for(j=1; j<=n2; j++)
{
R[j]=x[q+j];
//cout<<R[j];
}
// cout<<endl;
L[n1+1]=inf;
R[n2+1]=inf;
i=1;
j=1;
int k;
for(k=p; k<=r; k++)
{
if(L[i]<=R[j])
{
x[k]=L[i];
i++;
}
else
{
x[k]=R[j];
j++;
cnt=(cnt+n1-i+1);
}
}
}
int main()
{
int i;
int j;
while(scanf("%d",&n)!=EOF &&n!=0)
{
cnt=0;
for(i=1; i<=n; i++)
{
scanf("%d %d",&a,&x[i]);
}
merge_sort(1,n);
printf("%d\n",cnt%1000000);
}
return 0;
}
小结
相关文章
1.计数排序
点击打开链接