今天时间比较多,又刷了一道水题
依旧先给出题目链接:P1296 奶牛的耳语
题解思路
在这里先提醒一句:千万别被数据输入样例给骗了!
这题其实很容易写,假如输入序列是有序的,那么只要对每一个数据点,依次从小到大遍历,直到找到大于d的数据点的位置,得到一个
n
u
m
i
num_i
numi,然后依次累加得到最终的。
但是,这个有序的前提是不满足的,因此需要我们自己先对输入的数据进行一个排序。在这里,得到
n
u
m
i
num_i
numi我用的是蛮力枚举,单次复杂度是O(n),总的时间复杂度是O(n^2),也可以用二分查找来加速搜索,这样时间复杂度就会降低到O(nlogn)。排序这里我用了归并排序,时间复杂度为O(nlogn)。
下面给出我自己的AC代码:
#include <stdio.h>
#include <stdlib.h>
void merge(int left,int mid,int right,int n,int a[n],int b[n]){
int i,j,k=left;
for(i=left;i<=right;i++)
b[i]=a[i];
i=left;
j=mid+1;
while(i<=mid&&j<=right){
if(b[i]<b[j]){
a[k]=b[i];
i++;
k++;
}else{
a[k]=b[j];
j++;
k++;
}
}
while(i<=mid){
a[k]=b[i];
k++;
i++;
}
while(j<=right){
a[k]=b[j];
k++;
j++;
}
return;
}
void mergesort(int L,int R,int size,int a[size],int b[size]){
int left=L,right=R,mid=(left+right)/2,n=size;
if(left>=right){
return;
}
mergesort(left,mid,n,a,b);
mergesort(mid+1,right,n,a,b);
merge(left,mid,right,n,a,b);
return;
}
int main(int argc, char *argv[]) {
int n,d,num,i,j;
while(scanf("%d %d",&n,&d)!=EOF){
int a[n],b[n];
num=0;
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
mergesort(0,n-1,n,a,b);
for(i=0;i<n;i++){
for(j=i+1;j<n;j++){
if(a[i]+d>=a[j])
num++;
else
j=n;
}
}
printf("%d\n",num);
}
return 0;
}
写在最后的话:
说是要开始做点普及和提高题的我又来从水题上找信心了哈哈哈~~~~