[ICPC 2024 Kunming I] 两星级竞赛题解
题目描述
教育专家们出于某种原因,准备对 n 项竞赛进行评级。专家们已经决定了每项竞赛的评级结果,其中第 i 项竞赛被评为 si 星级竞赛。
据说每项竞赛都会依据 m 种属性进行评级,其中第 i 项竞赛的第 j 种属性记为 pi,j,每种属性的取值范围从 0 到 k(含两端)。一项竞赛的分数是其所有 m 种属性的总和。也就是说,令 vi 表示第 i 项竞赛的分数,我们有 vi=j=1∑mpi,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;
}

浙公网安备 33010602011771号