提交时间:2022-10-04 11:25:40

运行 ID: 57455

#include<iostream> #include<cstdio> #include<math.h> #include<algorithm> using namespace std; typedef pair<int , int> PII; int n; const int N = 1e5 + 10; struct p{ //记录分数 int t1; int t2; //记录期望 double pn; }person[N]; int pt[4][2]={0 , 0 , 1 , 1 , 0 , 1 , 1 , 0}; PII tot[N] , lv[N]; //记录排名 , double P = 1; bool cmp(PII a , PII b){ return a.first > b.first; } void dfs(int u){ if(u == n + 1){ //前面n层搜索完了 sort(tot + 1 , tot + n + 1 , cmp); // for(int i = 1 ; i <= n ; i++){ // cout << tot[i].first << ' ' << tot[i].second << endl; // // } // cout << endl; int last = -1 , t = 0; for(int i = 1 ; i <= n ; i++){ //如果当前和前面的不等,那么排名增加 1 if(tot[i].first != last) t++ , last = tot[i].first; int num = tot[i].second; //选手编号 person[num].pn += t * P; //计算这种可能对期望的影响 } } else{ //计算出当前人的总分,和前面的人进行排序以求得排名? (X) //用一个二元组保存每个人的总分和编号,到 n + 1 时进行排序,以分数为关键字 for(int i = 0 ; i < 4 ; i++){ //注意不要让先前的数据被新写入的覆盖了,保存当前状态并回溯 tot[u].first = pt[i][0] * person[u].t1 + pt[i][1] * person[u].t2; tot[u].second = u; for(int i = 1 ; i <= u - 1 ; i++) lv[i] = tot[i]; dfs(u + 1); for(int i = 1 ; i <= u - 1 ; i++) tot[i] = lv[i]; } } } int main(){ scanf("%d" , &n); for(int i = 1 ; i <= n ; i++) scanf("%d%d" , &person[i].t1 , &person[i].t2); int k = n; //快速幂 double a = 1.0/4.0; for( ; k ; k >>= 1 , a*=a) if(k%2 == 1) P *= a; dfs(1); for(int i = 1 ; i <= n; i++) printf("%lf\n" , person[i].pn) ; return 0; }