列表

详情


NC15733. K. GSS and Rating Calaulation

描述

The following text is simplily copied from MikeMirzayanov's blog.
http://codeforces.com/blog/entry/20762

You should notice that when calculating the rank of someone's score, the rank is defined as the number of contestants who has the score larger than or equal to his score score.

Now, given a list of contestants, and their Rating before the contest and their Score in the contest, your task is to calculate the rating after a real rated codeforces round. After the round 327.

You should notice that, a regular codeforces round (Div. 1) may have atmost 800 contestants.

Every one on the list have made at least one submission. So that all of their ratings should be calculated.

输入描述

The first line is an integer N, the number of contestants.

The following N lines, each line contains a string Namei and two integers Scorei and Ratingi.

输出描述

Output containts N lines, the i-th line should be one integer: the new rating of the i-th contestant in the list after the contest.

示例1

输入:

1
a 1 1500

输出:

1500

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 1046ms, 内存消耗: 616K, 提交时间: 2019-01-07 18:06:44

#include <bits/stdc++.h>
using namespace std;

namespace ejq{

const int maxn = 8000 + 5;

struct Contestant {
 int rating, rank, score, id;
 double delta;
}contestant[maxn];

int n, s;
int sorted_score[maxn];

double calc_p(double r_i, double r_j)
{
 return 1 / (1 + pow(10, (r_j - r_i) / 400));
}

double calc_seed(double rating, int i)
{
 double seed = 1;
 for (int j = 1; j <= n; j++)
  if (j != i)
   seed += calc_p(contestant[j].rating, rating);
 return seed;
}

double calc_d(int i, double rating, int rank)
{
 double l = 1, r = 4000;
 double curr_seed = calc_seed(rating, i);
 double m = sqrt(curr_seed * rank);
 while (r - l > 1e-6)
 {
  double mid = (l + r) / 2;
  double nseed = calc_seed(mid, i);
  if (nseed > m) l = mid;
  else r = mid;
 }
 return ((l + r) / 2 - rating) / 2;
}

int main()
{
 scanf("%d", &n);
 for (int i = 1; i <= n; i++)
 {
  scanf("%*s%d%d", &contestant[i].score, &contestant[i].rating);
  contestant[i].id = i;
  sorted_score[i] = contestant[i].score;
 }
 sort(&contestant[1], &contestant[n + 1], [](const Contestant &a, const Contestant &b) {
  return a.score > b.score;
 });
 sort(&sorted_score[1], &sorted_score[n + 1], greater<int>());
 for (int i = 1; i <= n; i++)
 {
  contestant[i].rank = upper_bound(&sorted_score[1], &sorted_score[n + 1], contestant[i].score, greater<int>()) - &sorted_score[1];
 }
 //--
 for (int i = 1; i <= n; i++)
 {
  contestant[i].delta = calc_d(i, contestant[i].rating, contestant[i].rank);
 }
 //--
 sort(&contestant[1], &contestant[n + 1], [](const Contestant &a, const Contestant &b) {
  return a.rating > b.rating;
 });
 if (n > 16) s = 4 * sqrt(n);
 else s = n;
 //--
 double sum_d = 0;
 for (int i = 1; i <= n; i++)
  sum_d += contestant[i].delta;
 double inc = 0;
 inc = -sum_d / n - 1;
 //cerr << inc << endl;
 for (int i = 1; i <= n; i++)
  contestant[i].delta += inc;
 double sum_s = 0;
 for (int i = 1; i <= s; i++)
  sum_s += contestant[i].delta;
 inc = min(max(-sum_s / s, -10.), 0.);
 for (int i = 1; i <= n; i++)
  contestant[i].delta += inc;
 sort(&contestant[1], &contestant[n + 1], [](const Contestant &a, const Contestant &b) {
  return a.id < b.id;
 });
 for (int i = 1; i <= n; i++)
  printf("%.0f\n", contestant[i].delta + contestant[i].rating);
 return 0;
}

}

int main()
{
 return ejq::main();
}

上一题