列表

详情


NC16040. 分数

描述

小胖参加了人生中最重要的比赛——MedoC资格赛。MedoC的资格赛由m轮构成,使用常见的“加权标准分”的规则。每位选手需要参加所有的m轮的比赛。在一轮中,能取得的分数为自己的成绩除掉最高分的成绩。每个选手的总分为每一轮获得的分数乘上这一轮比赛占得比重。如果在某一轮比赛中所有人获得了零分,那么所有选手在这一轮获得的分数都为0分。
比如说,资格赛一共3轮,三轮的权重分别为30%, 30%, 40%。在第一轮中,小胖获得了300分,最高分也为300分。在第二轮中,小胖获得了0分,最高分也为0分。在第三轮中,小胖获得了150分,最高分为300分,那么小胖的总分为(300/300)*30%+0*30%+(150/300)*40%=0.5。
一共有n位选手参加了比赛,其中成绩最高的k位选手能够晋级到初赛。如果有多人在分数线上同分,那么系统会随机在这些同分的人中选取,选满k个晋级为止。
小胖现在知道了每个选手每场比赛的成绩,但是由于他的疏忽,其中的某个人某场比赛的成绩消失了。所以更多人出线的情况变得未知起来。现在只知道成绩一定是0到C之间的一个整数(包含0和C)。
小胖想知道对于每个人的出线情况是怎么样的,也就是一定能出线,一定不能出线还是有可能出线。

输入描述

第一行四个正整数n,m,k,C (m <= 6, k <= n <= 500, C <= 500)。
接下来一行m个整数w1, w2, ..., wm,表示每场比赛的权重,第i场比赛的权重为wi/(w1+w2+...+wm),保证w>= 0且1 <= w+ w+ ... + w<= 1000。
接下来n行每行m个整数,第i个整数表示这个选手在第i场比赛中获得的成绩。如果这个数字为-1表示这个数据丢失,保证恰好有一个-1。

输出描述

n行每行输出一个1到3之间的整数。1表示一定出线,2表示一定不出线,3表示可能出线。

示例1

输入:

4 2 2 100
1 1
100 99
70 70
40 -1
100 39

输出:

1
3
3
2

原站题解

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

C++11(clang++ 3.9) 解法, 执行用时: 13ms, 内存消耗: 496K, 提交时间: 2020-02-15 21:17:02

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

typedef long long ll;
const ll mod=1000000007;
ll gcd(ll a,ll b)
{
	return b?gcd(b,a%b):a;
}
typedef unsigned long long score;
const int N=510;
int n,m,k,c,w[N],sco[N][10],sx,sy,ms[10],c1[N],c2[N];
score wt[N],s[N],t[N];
int main()
{
	scanf("%d%d%d%d",&n,&m,&k,&c);
	for(int i=0;i<m;i++)
	{
		scanf("%d",w+i);
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			scanf("%d",&sco[i][j]);
			if(sco[i][j]==-1)
			{
				sx=i;
				sy=j;
			}
		}
	}
	for(int x=0;x<c+1;x++)
	{
		sco[sx][sy]=x;
		for(int j=0;j<m;j++)
		{
			ms[j]=0;
			for(int i=0;i<n;i++)
			{
				ms[j]=max(ms[j],sco[i][j]);
			}
		}
		for(int j=0;j<m;j++)
		{
			wt[j]=w[j];
			if(ms[j]==0)
			{
				wt[j]=0;
				continue;
			}
			for(int k=0;k<m;k++)
			{
				if(j!=k&&ms[k]!=0)
				wt[j]*=ms[k];
			}
		}
		for(int i=0;i<n;i++)
		{
			s[i]=0;
			for(int j=0;j<m;j++)
			{
				s[i]+=wt[j]*sco[i][j];
				
			}
			t[i]=s[i];
		}
		sort(s,s+n);
		reverse(s,s+n);
		for(int i=0;i<n;i++)
		{
			if(t[i]>=s[k-1]) c1[i]++;
			if((k!=n)&&t[i]<=s[k]) c2[i]++;
		}
	}
	for(int i=0;i<n;i++)
	{
		if(c2[i]==0) puts("1");
		else if(c1[i]==0) puts("2");
		else puts("3");
	}
	return 0;
}

上一题