题目链接:ZOJ 3879 Capture the Flag
题意:给出n支队伍互相攻击服务器,有以下规则:
1.如果A队的服务器1被B队攻击成功,A队将失去n-1点分数,这n-1点分数会平分给成功攻击A队的服务器1的其他队伍。
eg:
共4个队
A B 1
C B 1
此时A队和C队都获得1.5(3/2)分,B队失去3分
2.如果一个队不能维护好他们的服务器,该队将失去n-1分,这n-1分平分给其他能维护好服务器的队伍。
eg:
1 1 0 1
0 1 1 1
针对服务器1(即第一行),只有C队没维护好,所以C队失去3分,A,B,D队各获得1(3/3)分。
针对服务器2(即第二行),只有A队没维护好,所以A队失去3分,C,B,D队各获得1(3/3)分。
输出c场比赛中每场比赛询问队伍的分数和排名。
注意:即使每个服务器被攻击多次,结算分数时只算一次。
AC代码:
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
const double ep=1e-5;
bool vis[110][110][110];
bool cvis[110][110];
struct node{
double p;
int id,rank;
};
struct node pp[110];
double p[110];
int Rank[110];
bool cmp(node a,node b){
return a.p>b.p;
}
bool cmp2(node a,node b){
return a.id<b.id;
}
void getRank(double arr[],int n){
int i;
for(i=1;i<=n;i++){
pp[i].id=i;
pp[i].p=arr[i];
}
sort(pp+1,pp+n+1,cmp);
int r=1;
pp[1].rank=r;
r++;
for(i=2;i<=n;i++){
if(pp[i-1].p-pp[i].p<=ep)
pp[i].rank=pp[i-1].rank;
else pp[i].rank=r;
r++;
}
for(i=1;i<=n;i++)
Rank[pp[i].id]=pp[i].rank;
}
int main()
{
int t;
int n,q,s,c;
int a,i,j;
int u,v,w,k;
scanf("%d",&t);
while(t--){
scanf("%d %d %d %d",&n,&q,&s,&c);
for(i=1;i<=n;i++){
p[i]=s*1.0;
Rank[i]=1;
}
while(c--){
memset(vis,false,sizeof vis);
memset(cvis,false,sizeof cvis);
scanf("%d",&a);
for(i=0;i<a;i++){
scanf("%d %d %d",&u,&v,&w);
cvis[v][w]=true;
vis[u][v][w]=true;
}
int count=0;
//被攻击的j队,k服务器
for(j=1;j<=n;j++){
for(k=1;k<=q;k++){
count=0;
for(i=1;i<=n;i++)
if(vis[i][j][k]) count++;
if(count==0) continue;
for(i=1;i<=n;i++)
if(vis[i][j][k]) p[i]+=(n-1)*1.0/count;
}
count=0;
for(k=1;k<=q;k++)
if(cvis[j][k]) p[j]-=(n-1);
}
int st;
bool vvis[110];
for(i=1;i<=q;i++){
count=0;
for(j=1;j<=n;j++){
vvis[j]=false;
scanf("%d",&st);
if(!st) count++;// not work well
else vvis[j]=true;
}
if(count==0) continue;
for(j=1;j<=n;j++){
if(!vvis[j]) p[j]-=(n-1);
else p[j]+=(n-1)*count*1.0/(n-count);
}
}
getRank(p,n);
scanf("%d",&u);
while(u--){
scanf("%d",&v);
printf("%.8lf %d\n",p[v],Rank[v]);
}
}
}
return 0;
}
/*
1
4 2 2500 5
0
1 1 1 1
1 1 1 1
4
1 2 3 4
2
1 2 1
3 2 1
1 1 1 1
1 1 1 1
4
1 2 3 4
1
1 2 2
1 1 1 1
1 1 1 0
4
1 2 3 4
0
0 0 0 0
0 0 0 0
4
1 2 3 4
0
1 1 1 1
1 1 1 1
2
1 4
2500.00000000 1
2500.00000000 1
2500.00000000 1
2500.00000000 1
2501.50000000 1
2497.00000000 4
2501.50000000 1
2500.00000000 3
2505.50000000 1
2495.00000000 4
2502.50000000 2
2497.00000000 3
2499.50000000 1
2489.00000000 4
2496.50000000 2
2491.00000000 3
2499.50000000 1
2491.00000000 3
*/