Пример #1
0
 /// <summary>
 /// 返回OI比赛Standing
 /// </summary>
 /// <param name="skip"></param>
 /// <param name="top"></param>
 /// <param name="HasVirtual"></param>
 /// <returns></returns>
 /// <exception cref="ContestTypeMismatchException"></exception>
 /// <exception cref="ContestNotEndedException"></exception>
 public List<OIStanding> GetOIStanding(int skip, int top,bool HasVirtual,bool HasNotSubmit)
 {
     if (Type != ContestType.OI)
         throw new ContestTypeMismatchException();
     using (var db = new CHDB())
     {
         var con = (from c in db.CONTESTs
                    where c.ID==ID
                    select c).Single();
         if (DateTime.Now <= RelativeEndTime && !User.CurrentUser.IsAdmin && !Owner.Contains(User.CurrentUserName))
             throw new ContestNotEndedException();
         int count = Problems().Count();
         var lst = db.GetOIStanding(ID, RelativeNow, skip, top, HasVirtual, HasNotSubmit).ToArray();
         var ret = new List<OIStanding>();
         for (int i = 0; i < lst.Length; i+=count)
         {
             var desp=new List<OIStanding.DescriptionClass>();
             for (int jj = 0; jj < count; jj++)
             {
                 int j = i + jj;
                 desp.Add(new OIStanding.DescriptionClass()
                 {
                     ExecTime = lst[j].ExecuteTime ?? 0,
                     Score = lst[j].Score ?? 0,
                     IsScored = null != lst[j].Score
                 });
             }
             ret.Add(new OIStanding()
             {
                 IsVirtual = lst[i].Type == (int)AttendType.Virtual,
                 desp = desp,
                 TotalScore = desp.Sum(x => x.Score),
                 TotalTime = desp.Sum(x => x.ExecTime),
                 User = lst[i].User
             });
         }
         return ret;
     }
 }
Пример #2
0
        void CalcRating(CONTEST con, CHDB db)
        {
            List<string> Rank = new List<string>();
            List<int> Rating = new List<int>();
            double[] exp;
            int probs;
            int[] dat1;
            int[] dat2;

            switch ((Contest.ContestType)con.Type)
            {
                case Contest.ContestType.OI:
                    var tmp_oi = db.GetOIStanding(con.ID, DateTime.Now, 0, con.CONTEST_ATTEND.Count, false, false).ToArray();
                    dat1 = new int[con.CONTEST_ATTEND.Count + 100];
                    dat2 = new int[con.CONTEST_ATTEND.Count + 100];
                    probs = con.PROBLEMs.Count;
                    for (int i = 0; i < tmp_oi.Length; i += probs)
                    {
                        Rank.Add(tmp_oi[i].User);
                        int k = i / probs;
                        dat1[k] = dat2[k] = 0;
                        for (int j = i; j < i + probs; j++)
                        {
                            dat1[k] += tmp_oi[j].Score ?? 0;
                            dat2[k] += tmp_oi[j].ExecuteTime ?? 0;
                        }
                    }
                    break;
                case Contest.ContestType.CF:
                    var tmp_cf = db.GetCFStanding(con.ID, DateTime.Now, 0, con.CONTEST_ATTEND.Count, false, false).ToArray();
                    dat1 = new int[con.CONTEST_ATTEND.Count + 100];
                    dat2 = new int[con.CONTEST_ATTEND.Count + 100];
                    probs = con.PROBLEMs.Count;
                    for (int i = 0; i < tmp_cf.Length; i += probs)
                    {
                        Rank.Add(tmp_cf[i].User);
                        int k = i / probs;
                        dat1[k] = dat2[k] = 0;
                        for (int j = i; j < i + probs; j++)
                        {
                            dat1[k] += (tmp_cf[j].Rating ?? 0) + (tmp_cf[j].SuccessfulHunt ?? 0) * 100 - (tmp_cf[j].FailedHunt ?? 0) * 25;
                        }
                    }
                    break;
                case Contest.ContestType.ACM:
                    var tmp_acm = db.GetACMStanding(con.ID, DateTime.Now, 0, con.CONTEST_ATTEND.Count, false, false).ToArray();
                    dat1 = new int[con.CONTEST_ATTEND.Count + 100];
                    dat2 = new int[con.CONTEST_ATTEND.Count + 100];
                    probs = con.PROBLEMs.Count;
                    for (int i = 0; i < tmp_acm.Length; i += probs)
                    {
                        Rank.Add(tmp_acm[i].User);
                        int k = i / probs;
                        dat1[k] = dat2[k] = 0;
                        for (int j = i; j < i + probs; j++)
                        {
                            dat1[k] += (tmp_acm[j].IsAC ?? false) ? 1 : 0;
                            dat2[k] += (tmp_acm[j].ACTime ?? 0) + (tmp_acm[j].FailedTimes ?? 0) * 20;
                        }
                    }
                    break;
                default:
                    throw new NotImplementedException();
            }
            foreach (var u in Rank)
            {
                var Rat = (from r in db.RATINGs
                           where r.USER1.Name == u
                           orderby r.CONTEST1.EndTime descending
                           select r.Rating1).FirstOrDefault();
                Rating.Add(Rat == 0 ? 1500 : Rat);
            }
            int n = Rank.Count;
            if (n < 1)
                return;
            int m = (n + 1) / 2;
            for (int i = 0, j; i < n; i = j)
            {
                for (j = i + 1; j < n && dat1[j] == dat1[i] && dat2[j] == dat2[i]; j++) ;
                for (int k = i; k < j; k++) dat1[k] = (i + j - 1) / 2;
            }
            exp = new double[n];
            double mid = (double)Rating.Sum() / n;
            for (int i = 0; i < n / 2; i++)
                exp[i] = mid + (3000 - mid) / Math.Pow(m - 1, 3) * Math.Pow(m - i - 1, 3);
            exp[n / 2] = mid;
            for (int i = n / 2 + 1; i < n; i++)
                exp[i] = mid - mid / Math.Pow(n - m, 3) * Math.Pow(i + 1 - m, 3);
            int weight = con.Weight;
            for (int i = 0; i < n; i++)
            {
                Rating[i] += (int)Math.Round((exp[dat1[i]] - Rating[i]) * Math.Pow(n, 1.0 / 8.0) / weight);
                Rating[i] = Math.Max(Rating[i], 1);
                Rating[i] = Math.Min(Rating[i], 3000);
            }
            for (int i = 0; i < n; i++)
            {
                var name = Rank[i];
                foreach (var u in (from u in db.USERs
                                   where u.Name == name
                                   select u))
                {
                    u.RATINGs.Add(new RATING()
                    {
                        CONTEST1 = con,
                        Rating1 = Rating[i]
                    });
                }
            }
        }