没有练过多少C,这回写起来,还真的有好多东西要学!
很多小的地方要注意,比如if中的条件要写“==”而不能写“=”,虽然不会报错,可是结果是错的!
还有快排忘记写break,找错找了好久,真是马虎呀!
输出勿忘加上换行!!之前写Java用println都习惯了,没有注意到
写的比较麻烦,用了一次计算名次的算法O(n^2),一次快排,所以时间比较长 230MS
代码:
#include <stdio.h>
#include <stdlib.h>
/*
by qr 2014-8-31 jobdu 1167
September is coming~~ let's fighting!!
采用计算名次的算法和快排
*/
void quicksort(int arr[],int i,int j){
if(i==j)
return;
int pivot=arr[i];
int m=i;
int n=j;
while(m<n){
while(m<n){
if(arr[n]<pivot){ //无需等号
arr[m]=arr[n]; //找到一个比支点小的就放到前面,该位空出
break; //!!!少写了!!!! forget the "break"!!!!
}
n--;
}
while(m<n){
if(arr[m]>pivot){
arr[n]=arr[m]; //之前空出的n指向的位置被填上
break;
}
m++;
}
}//跳出循环时 m=n
arr[m]=pivot;
if(m<j)
quicksort(arr,m+1,j);
if(m>i)
quicksort(arr,i,m-1);
}
int main() {
int arr[10000];
int rank1[10000]; //计算名次
int n;
int rank2[10000];
while (scanf("%d",&n) != EOF) {
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
rank1[i]=0;
}
for(int p=0;p<n;p++){
for(int q=p;q<n;q++){
if(arr[p]<arr[q]){
rank1[q]++;
}else if(arr[p]>arr[q]){
rank1[p]++;
}
}
}
quicksort(arr,0,n-1); //sort
rank2[0]=1;
for(int m=1;m<n;m++){
if(arr[m]==arr[m-1]){ // == not =
rank2[m]=rank2[m-1];
}else{
rank2[m]=rank2[m-1]+1;
}
}
for(int j=0;j<n-1;j++){
printf("%d ",rank2[rank1[j]]);
}
printf("%d\n",rank2[rank1[n-1]]);
}
return 0;
}
查看其他人的代码,有利用结构体和两次快排,思想类似,时间10MS。
在论坛里看到一个30行的代码,代码简洁些,但是时间长 850MS。这里贴出来,转载自九度论坛http://t.jobdu.com/thread-7890-2-1.html 30楼
代码:
#include<stdio.h>
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&(n>=1)&&(n<=10000))
{
int a[n],b[n],i,j,k;
for(i=0;i<n;i++) scanf("%d",&a[i]);
for(i=0;i<n;i++) // 将次序存至b数组中,此次计算中相同的数值重复计算了次序
{
int seq=1;
for(j=0;j<n;j++)
if(a[i]>a[j]) ++seq;
b[i]=seq;
}
for(k=1;k<=n;k++)//对b数组处理,将重复计算的次序去除 编者注:名次是1-n,即k的范围
{
int count=-1;
for(i=0;i<n;i++)
if(b[i]==k) ++count; //这个名次的有多少 count初值应为-1
for(i=0;i<n;i++)
if(b[i]>k) b[i]=b[i]-count; //减去重复的
if(count==-1) break; //巧妙!!!
}
printf("%d",b[0]);
for(i=1;i<n;i++) printf(" %d",b[i]);
printf("\n");
}
return 0;
}