题解 P5759 【[NOI1997]竞赛排名】
P5759 [NOI1997]竞赛排名
以极其暴力的模拟过了此题
解释一下这些符号
-
-
-
y_{ij}=\begin{cases}0&\sum_{i=1}^N|x_{ij}-avg_J|=0\\\frac{x_{ij}-avg_j}{\frac{1}{N}\sum_{i=1}^N|x_{ij}-avg_j|}&\sum_{i=1}^N|x_{ij}-avg_J|\ne0\end{cases} 当
\sum_{i=1}^N|x_{ij}-avg_J| 的值为零时y_{ij} 的值为0 . 当\sum_{i=1}^N|x_{ij}-avg_J| 的值不为零时y_{ij} 的值为\frac{x_{ij}-avg_j}{\sum_{i=1}^N|x_{ij}-avg_J|\div N} 用人话来讲就是 用 (
x 与 第j 科平均分相差的分数) 去除以 (x 每一科的分数与平均分的差的平均值) -
sumy_i=\sum_{k=1}^3y_{jk}+0.8\sum_{k=4}^8y_{jk} 前三科成绩的位置分直接加,后四科要
\times0.8 再相加.(语数英?)
读懂题目模拟就比较好打了.
另外注意double类型的等于判断.
#include <stdio.h>
#include <stdlib.h>
const double dis=1e-6;
typedef struct _Student
{
int ind;
int mark[9];
int allMark;
double y[9];
double sumy;
}Stu;
Stu a[10086];
int cmp(const void* a,const void* b)
{
Stu* pa=a;
Stu* pb=b;
double tmp=pa->sumy-pb->sumy;
tmp=tmp>0?tmp:-tmp;
/*奇妙的判断,省略了else*/
if(tmp>dis)return pa->sumy<pb->sumy?1:-1;
if(pa->allMark!=pb->allMark)return pa->allMark<pb->allMark?1:-1;
return pa->ind-pb->ind;
}
int n;
int sumJMark[11];
double avg[11];
double tmp;
double cha;
int main()
{
int i,j,k;
scanf("%d",&n);
for(i=0;i<n;++i)
{
a[i].ind=i;
for(j=0;j<8;++j)
{
scanf("%d",&a[i].mark[j]);
a[i].allMark+=a[i].mark[j];
sumJMark[j]+=a[i].mark[j];
}
}
for(i=0;i<8;++i)
{
avg[i]=((double)sumJMark[i])/((double)n);
}
for(j=0;j<8;++j)
{
for(i=0;i<n;++i)
{
cha=0;
for(k=0;k<n;++k)
{
tmp=a[k].mark[j]-avg[j];
cha+=(tmp>0)?tmp:-tmp;
}
cha/=n;
if(cha)a[i].y[j]=(a[i].mark[j]-avg[j])/cha;
}
}
for(k = 0; k < 3; ++k)a[i].sumy+=a[i].y[k];
for(k = 3; k < 8; ++k)a[i].sumy+=0.8*a[i].y[k];
qsort(a,n,sizeof(Stu),cmp);
for(i=0;i<n;++i)printf("%d\n",a[i].ind+1);
return 0;
}