ZOJ 3879 Capture the Flag 15年浙江省赛K题

每年省赛必有的一道模拟题,描述都是非常的长,题目都是蛮好写的...

sigh... 比赛的时候没有写出这道题目 :(

 

题意:首先输入4个数,n,q,p,c代表有n个队伍,q个服务器,每支队伍的初始分数p,

还有c次操作对于每次操作,首先输入一个k,代表k次攻击每次攻击有三个数,a,b,c,

代表a通过c服务器成功的攻击了b对于每次成功的攻击,b会失去n-1分,

这n-1分会平分给通过同一服务器攻击b的几支队伍然后是q行,每行n个数,

分别代表1~n是否成功维护了,1为成功,0为不成功不成功的队伍会失去n-1分,

这失去的分会平分给成功维护的那些队伍然后输入k个数,询问这k支队伍的分数

 

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-7      ;
const int N = 210            ;
const int M = 1100011*2      ;
const ll P = 10000000097ll   ;
const int MAXN = 10900000    ;

struct node {
    int id, rank;
    double score;
} a[105];

int n, q, c, t;
double p;
bool vis[105][105][15], hsh[105];

int cmp1 (node a,node b) {
    return a.score > b.score;
}

int cmp2 (node a,node b) {
    return a.id < b.id;
}

int main () {
    int i, j, k;
    scanf ("%d",&t);
    while (t--) {
        scanf ("%d%d%lf%d", &n, &q, &p, &c);
        for (i = 0; i <= n; ++i) {
            a[i].id = i;
            a[i].rank = 1;
            a[i].score = p;
        }
        while (c--) {
            scanf("%d",&k);
            memset (vis, 0, sizeof (vis));
            while(k--) {
                int atk, def, sev;
                scanf("%d%d%d", &atk, &def, &sev);
                if (vis[atk][def][sev]) continue;
                vis[atk][def][sev] = true;
            }
            for (i = 1; i <= q; ++i) {
                for (j = 1; j <= n; ++j) {          //防守方
                    int cnt = 0;
                    for (k = 1; k <= n; ++k) {      //攻击方
                        if (vis[k][j][i])           //统计攻击j的队伍有几支
                            ++cnt;
                    }
                    if (!cnt)   continue;
                    double ss = 1.0 * (n - 1) / cnt;//平分
                    a[j].score -= (n - 1);          //防守方失去n-1
                    for (k = 1; k <= n; ++k) {
                        if (vis[k][j][i])           //攻击方得到分数
                            a[k].score += ss;
                    }
                }
            }

            for (i = 1; i <= q; ++i) {              //服务器
                memset (hsh, 0, sizeof (hsh));
                int cnt = 0;
                for (j = 1; j <= n; ++j) {
                    int x;
                    scanf ("%d",&x);
                    if (x) {                        //成功维护的队伍数
                        hsh[j] = true;
                        ++cnt;
                    } else {
                        hsh[j] = false;
                        a[j].score -= (n - 1);
                    }
                }
                if(cnt == n)    continue;
                double ss = 1.0 * (n - 1) / cnt;
                ss = ss * (n - cnt);
                for (j = 1; j <= n; ++j) {
                    if (hsh[j]) {
                        a[j].score += ss;
                    }
                }
            }
            sort (a + 1, a + n + 1, cmp1);
            for (i = 1; i <= n; ++i) {              //更新排名
                if (i != 1) {
                    if (fabs(a[i].score - a[i - 1].score) < 1e-5)
                        a[i].rank = a[i - 1].rank;
                    else
                        a[i].rank = i;
                } else {
                    a[i].rank = i;
                }
            }
            sort (a + 1, a + n + 1, cmp2);
            scanf ("%d", &k);
            while (k--) {
                int x;
                scanf ("%d",&x);
                printf ("%.5f %d\n",a[x].score, a[x].rank);
            }
        }
    }

    return 0;
}

 

posted @ 2015-05-07 15:06  Jeremy Wu  阅读(282)  评论(0编辑  收藏  举报