COCI CONTEST #3 29.11.2014 HONI

来源:互联网 发布:导弹惯性制导难度知乎 编辑:程序博客网 时间:2024/06/11 19:59

题目大意:比赛已经进行到了第三场,开始有人预测第三场比赛选手们的排名了。怎么预测呢,我们假设存在以下的规律:
如果选手A在前两场比赛的分数都高于B,则第三场比赛选手A的分数不可能低于B。
排名的规则是这样的,总分相同则名次并列。比如说,如果有5个选手的分数为1000,1000,900,900,800,则他们的名次为1,1,3,3,5.
现在我们知道N个选手在前两场比赛的成绩,如果上述规律始终成立,预测每个选手的最高排名和最低排名。
比赛选手的分数在0~650之间。

思路:这道题非常好想到求一个二维的前缀和。假设选手A的成绩为a1, a2,那么我们将一个统计的数组M[a1][a2]增加1。然后统计M的前缀和为P,后缀和为S。A选手的最好排名就是S[a1+1][a2+1] + 1。那么是不是A选手的最坏成绩就是N-S[a1-1][a2-1]呢?其实不是,若存在两人 X、Y,X的成绩是(q, 0), Y的成绩是(q, 650)。那么Y的最坏成绩也是X的最好成绩,因为X第三次比赛如果取得了650分,他最多就是和Y持平。

代码:

#include<cstdio>#define MAXP 666#define MAXN 500006int mt[MAXP][MAXP], n, q[MAXP][MAXP], h[MAXP][MAXP];int f[MAXN], s[MAXN];int main(){    scanf("%d", &n);    for(int i = 1; i <= n; i ++)    {        scanf("%d%d", &f[i], &s[i]);        ++f[i]; ++s[i];        mt[f[i]][s[i]] ++;    }    for(int i = 1; i <= 651; i ++)    {        int tmp = 0;        for(int j = 1; j <= 651; j ++)        {            tmp += mt[i][j];            if(i > 0) q[i][j] = tmp + q[i-1][j];        }    }    for(int i = 651; i >= 1; i --)    {        int tmp = 0;        for(int j = 651; j >= 1; j --)        {            tmp += mt[i][j];            h[i][j] = tmp + h[i+1][j];        }    }    for(int i = 1; i <= n; i ++)        printf("%d %d\n", h[f[i]+1][s[i]+1] + 1, n - q[f[i]-1][s[i]-1] - (f[i] == 651) * mt[1][s[i]] - (s[i] == 651) * mt[f[i]][1]);    return 0;}
0 0
原创粉丝点击