专栏文章
题解:AT_abc433_e [ABC433E] Max Matrix 2
AT_abc433_e题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min1284c
- 此快照首次捕获于
- 2025/12/01 18:49 3 个月前
- 此快照最后确认于
- 2025/12/01 18:49 3 个月前
退役前最后一场 ABC 吧。
Solution AT_abc433_e
先把行和列拆开。
我们对于一个行的数组,给它排序。由于一行必然要填 个数,也就是说对于 如果没有 个小于等于 的数显然无解。设 排序之后位置是 ,则 的数的个数为 (前面 行,每行都要用 个)。
对于列其实也差不多,给它排序,如果没有 个小于等于 的数无解。
然后因为一个数不能同时出现在两行或者两列,所以 必须互异,否则无解。
然后你考虑开始填数。
-
先把限制最强的填了:如果 ,则直接把 填到 。
-
然后填次强的:如果 ,找到一个 且 还没有被填的位置填上 。对于列同理,找到一个 且还没有被填数的位置填上 即可。
-
然后还剩下一些位置没有被填。我们考虑: 越小,可以填的数越少,限制越强。综上,我们把没有填的位置塞进一个
vector里,然后按照 排序,然后从 开始,双指针遍历:- 如果当前的数还没有被用,则把这个数填到这个位置里,然后换到下一个数。
- 如果当前的数已经被用了,直接换到下一个数。
不难发现这样是最能满足这些限制的方案。
但是你会 WA 个点。原因是,给你一组 hack:
CPP1
2 2
2 4
2 4
你可能会输出
CPP2 1
3 4
也可能输出
CPP2 3
1 4
但是这两个都是不符合条件的。所以填完之后,我们再检查一遍,如果还是不满足,就无解了。
Code
CPP#include<bits/stdc++.h>
using namespace std;
const int N=400005;
#define fi first
#define se second
vector<int>ans[N];
int p[N],q[N],a[N],b[N],vis[N];
int n,m;
vector<pair<int,pair<int,int> > >g;
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
p[i]=a[i];
ans[i].clear();
ans[i].resize(m+1);
}
for(int i=1;i<=m;i++){
cin>>b[i];
q[i]=b[i];
}
for(int i=1;i<=n*m;i++)vis[i]=0;
sort(p+1,p+n+1);
sort(q+1,q+m+1);
for(int i=1;i<=n;i++){
if(p[i]-(i-1)*m<m){
cout<<"No\n";
return;
}
if(p[i]==p[i-1]){
cout<<"No\n";
return;
}
}
for(int i=1;i<=m;i++){
if(q[i]-(i-1)*n<n){
cout<<"No\n";
return;
}
if(q[i]==q[i-1]){
cout<<"No\n";
return;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i]==b[j]){
ans[i][j]=a[i];
vis[a[i]]=1;
}
}
}
for(int i=1;i<=n;i++){
if(vis[a[i]])continue;
for(int j=1;j<=m;j++){
if(ans[i][j]==0){
if(b[j]>a[i]){
ans[i][j]=a[i];
vis[a[i]]=1;
break;
}
}
}
}
for(int j=1;j<=m;j++){
if(vis[b[j]])continue;
for(int i=1;i<=n;i++){
if(ans[i][j]==0){
if(a[i]>b[j]){
ans[i][j]=b[j];
vis[b[j]]=1;
break;
}
}
}
}
g.clear();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!ans[i][j]){
g.push_back(make_pair(min(a[i],b[j]),make_pair(i,j)));
}
}
}
sort(g.begin(),g.end());
int i=1;
for(auto t:g){
int x=t.se.fi,y=t.se.se;
while(i<=n*m&&vis[i])i++;
ans[x][y]=i;i++;
}
for(int i=1;i<=n;i++){
int mx=0;
for(int j=1;j<=m;j++)mx=max(mx,ans[i][j]);
if(mx!=a[i]){
cout<<"No\n";
return;
}
}
for(int j=1;j<=m;j++){
int mx=0;
for(int i=1;i<=n;i++){
mx=max(mx,ans[i][j]);
}
if(mx!=b[j]){
cout<<"No\n";
return;
}
}
cout<<"Yes\n";
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<ans[i][j]<<' ';
}
cout<<'\n';
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)solve();
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...