[ICPC 2024 Kunming I] 两星级竞赛题解

题目描述

教育专家们出于某种原因,准备对 n 项竞赛进行评级。专家们已经决定了每项竞赛的评级结果,其中第 i 项竞赛被评为 si​ 星级竞赛。

据说每项竞赛都会依据 m 种属性进行评级,其中第 i 项竞赛的第 j 种属性记为 pi,j​,每种属性的取值范围从 0 到 k(含两端)。一项竞赛的分数是其所有 m 种属性的总和。也就是说,令 vi​ 表示第 i 项竞赛的分数,我们有 vi​=j=1∑m​pi,j​。

如果一项星级更高的赛事有更高的分数,看起来会比较自然。专家们要求,对于任意两项竞赛 1≤i,j≤n,若 si​>sj​,则必须有 vi​>vj​。不幸的是,专家们忘了采集一些竞赛部分(甚至全部)属性的数据。作为专家们的助手,您被要求填充这些不存在的属性值,使得上述限制条件对任意两项竞赛都成立。

输入格式

有多组测试数据。第一行输入一个整数 T 表示测试数据组数,对于每组测试数据:

第一行输入三个整数 n,m 和 k(2≤n≤4×105,1≤m≤4×105,n×m≤4×105,1≤k≤109)表示竞赛的数量,每项竞赛有几种属性,以及每种属性取值的上限。

对于接下来 n 行,第 i 行首先输入一个整数 si​(1≤si​≤109)表示第 i 项竞赛被评定的星级。接下来输入 m 个整数 pi,1​,pi,2​,⋯,pi,m​(−1≤pi,j​≤k)。若 pi,j​=−1 则第 i 项竞赛的第 j 种属性值不存在,您需要填充该属性值;否则若 pi,j​≥0 则第 i 项竞赛的第 j 种属性值已被给定,您不应该更改它。

保证所有数据 n×m 之和不超过 4×105。

输出格式

对于每组数据:

如果可以填充所有不存在的属性值并满足限制条件,首先输出一行 Yes。接下来输出 n 行,第 i 行包含 m 个由单个空格分隔的整数 qi,1​,qi,2​,⋯,qi,m​(0≤qi,j​≤k),表示完成填充之后的第 i 项竞赛的 m 种属性值。若 pi,j​=−1,那么 qi,j​ 就是您填充的值;否则若 pi,j​≥0,那么 qi,j​=pi,j​。如果有多种答案,您可以输出任意一种。

如果无法满足限制条件,仅需输出一行 No。

输入输出样例

输入 #1复制

5
3 4 5
5 1 3 -1 -1
2 -1 5 -1 5
3 3 -1 -1 4
2 3 10
10000 5 0 -1
1 10 10 10
2 3 10
10 1 2 3
100 4 5 6
2 3 10
100 1 2 3
10 4 5 6
2 3 10000
100 -1 -1 -1
1 -1 -1 -1

输出 #1复制

Yes
1 3 5 4
0 5 0 5
3 3 2 4
No
Yes
1 2 3
4 5 6
No
Yes
2024 5 26
11 45 14

说明/提示

对于第二组样例数据,即使我们将唯一的 −1 填入最大的可能值 10,第一项竞赛的分数也只有 15 分,并不大于第二项竞赛的分数 30 分。

思路

贪心。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long t,n,k,m,p,sx=-1,as=0;
struct one{
	long long s,l,r,d,e;
}a[400005];
bool cmp(one a1,one b1){
	if(a1.s!=b1.s){
		return a1.s<b1.s;
	}
	else{
		return a1.r<b1.r;
	}
} 
bool cmp2(one a1,one b1){
	return a1.e<b1.e;
} 
vector<long long> v[400005];
int main(){
	cin>>t;
    while(t--){
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++){
        	cin>>a[i].s;
        	v[i].clear();
        	a[i].l=a[i].r=0;
        	a[i].e=i;
        	for(int j=1;j<=m;j++){
        		cin>>p;
        		if(p==-1){
        			a[i].r++; 
				}
				else{
					a[i].l+=p;
				}
				v[i].push_back(p);
			}
			a[i].r=a[i].r*k+a[i].l;
		}
		sort(a+1,a+n+1,cmp);
		sx=-1;
		as=0;
		for(int i=1;i<=n;i++){
			if(a[i].s!=a[i-1].s||i==1){
				if(sx+1<=a[i].l){
					sx=a[i].l;
				}
				else if(sx+1<=a[i].r){
					sx++;
				}
				else{
					as=1;
					break;
				}
				a[i].d=sx;
			}
			else{
				if(sx<=a[i].l){
					sx=a[i].l;
				}
				else if(sx<=a[i].r){
					sx=sx;
				}
				else{
					as=1;
					break;
				}
				a[i].d=sx;				
			}
		}
		if(as==1){
			cout<<"No"<<endl;
		}
		else{
			sort(a+1,a+n+1,cmp2);
			cout<<"Yes"<<endl;
			for(int i=1;i<=n;i++){
				for(int j=0;j<m;j++){
					if(v[i][j]==-1){
						if(a[i].l==a[i].d){
							cout<<0<<" ";
						}
						else{
							if(a[i].l+k<=a[i].d){
								a[i].l+=k;
								cout<<k<<" ";
							}
							else{
								cout<<a[i].d-a[i].l<<" ";
								a[i].l=a[i].d;
							}
						}
					}
					else{
						cout<<v[i][j]<<" ";
					}
				}
				cout<<endl;
			}
		}
    }
	return 0;
}

posted @ 2025-10-14 19:41  bz02_2023f2  阅读(8)  评论(0)    收藏  举报  来源