您的位置:首页 > 其它

SZU:B85 Alec's Eggs

2013-07-07 17:06 232 查看

Description








Eggs

Alec has a lot of eggs. One day, he want to sort them in a ascending sequence by weight. But he only can switch two eggs which are adjoining by each other because he has two hands only. Now he ask for your help, and you are enthusiastic. You decide help him calculate the total numbers of switch he need at least.

Attention: the weight of each egg less than 100,000,000 units.

Input

There are multiply test case.The first line describe the number of test case

. For each test case, the first line describe the number of eggs that Alec has,

. The second line describe the weight of each eggs splited by a space.

Output

Output the total number of switch that Alec need at least. One line for each test case. The total number may be very very large but fited in 64-bit integer.

Sample Input

2
2
2 1
2
2 3


Sample Output

1
0

题意:

题意:将相邻的两个元素进行排序,用到二路归并算法,

贴上代码:

#include <stdio.h>
#include <stdlib.h>

#define MAX 100001

int n, a[MAX], t[MAX];
long long sum;

/* 归并 */
void Merge(int l, int m, int r)
{
/* p指向输出区间 */
int p = 0;
/* i、j指向2个输入区间 */
int i = l, j = m + 1;
/* 2个输入区间都不为空时 */
while(i <= m && j <= r)
{
/* 取关键字小的记录转移至输出区间 */
if (a[i] > a[j])
{
t[p++] = a[j++];
/* a[i]后面的数字对于a[j]都是逆序的 */
sum += m - i + 1;
}
else
{
t[p++] = a[i++];
}
}
/* 将非空的输入区间转移至输出区间 */
while(i <= m) t[p++] = a[i++];
while(j <= r) t[p++] = a[j++];
/* 归并完成后将结果复制到原输入数组 */
for (i = 0; i < p; i++)
{
a[l + i] = t[i];
}
}

/* 归并排序 */
void MergeSort(int l, int r)
{
int m;
if (l < r)
{
/* 将长度为n的输入序列分成两个长度为n/2的子序列 */
m = (l + r) / 2;
/* 对两个子序列分别进行归并排序 */
MergeSort(l, m);
MergeSort(m + 1, r);
/* 将2个排好的子序列合并成最终有序序列 */
Merge(l, m, r);
}
}

int main()
{
int i;
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
if (n == 0) break;
sum = 0;
for(i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
MergeSort(0, n - 1);
printf("%lld\n", sum);
}
return 0;
}


上面代码速度没有优化,

下面的是网友的代码:

#include <stdio.h>
#define MAX 100000
int n,flag,a[MAX],b[MAX];
long long cnt;
void Merge(int *res,int *cop,int l,int lt,int r,int rt)
{
int base=l;
while(base<=rt)
{
while((l<=lt && cop[l]<=cop[r]) || (l<=lt && r>rt)) res[base++]=cop[l++];
while((r<=rt && cop[l]>cop[r]) || (r<=rt && l>lt))
{
cnt+=lt-l+1;
res[base++]=cop[r++];
}
}
}
void MergeSort()
{
int step=2,semi,c,s,i,l,r,lt,rt;
int *res=NULL,*cop=NULL;
while(step<2*n)
{
c=n/step;
s=n%step;
semi=step/2;
if(s>semi) c++;
flag++;
if(flag%2)
{
res=b;
cop=a;
}
else
{
res=a;
cop=b;
}
for(i=0;i<c;i++)
{
l=i*step;
r=l+semi;
lt=r-1;
rt=(n-1)<(l+step-1)?(n-1):(l+step-1);//边界非整段处理
Merge(res,cop,l,lt,r,rt);
}
if(rt<n-1){
for(i=rt+1;i<n;i++) res[i]=cop[i];//非常关键,尾部剩余有序要记得拷贝
}
step*=2;
}
}

int main()
{
int i;
int t;
scanf("%d", &t);
while(t--){
scanf("%d",&n);

flag=cnt=0;
for(i=0;i<n;i++) scanf("%d",&a[i]);
MergeSort();
printf("%lld\n",cnt);

}
return 0;
}


另一个版本:

long long a[100004],b[100004];int N;

long long total,i,j;

void Mergesort(int start,int end)
{
if(start<end){
int i,j,mid=(start+end)/2;
Mergesort(start,mid);
Mergesort(mid+1,end);
int t=start;j=mid+1;i=start;
while(i<=mid && j<=end){
if (a[i]<=a[j])
b[t++]=a[i++];
else{
b[t++]=a[j++];
total+=mid-i+1;
}
}
while (i<=mid)
b[t++]=a[i++];
while (j<=end)
b[t++]=a[j++];
for(i=start;i<=end;i++)
a[i]=b[i];
}
}

int main()
{
int t;
double ac;
scanf("%d", &t);
while (t--) {
scanf("%d",&N);
total=0;
for(i=0;i<N;i++)
scanf("%lld",&a[i]);
Mergesort(0,N-1);
ac = (total+N)/(N*1.0);
printf("%.2f\n",ac);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: