列表

详情


NC21351. 矩阵构造

描述

定义二进制矩阵为每个元素都是0或者1的矩阵
现在有一个二进制矩阵,但是有些格子缺失了,用 '?'表示
现在知道这个矩阵每行的信息
并且知道矩阵每列的信息,但是不知道具体这些列是对应这个矩阵的哪一列

给每个缺失的格子补上后,求满足条件的字典序最小的二进制矩阵
矩阵的字典序为将每行的字符拼接后的字符串代表的字典序

输入描述

第一行输入两个整数n,m表示二进制矩阵的行数和列数(1 ≤ n,m ≤ 30)
接下来n行每行m个字符,第i行描述矩阵的第i行的信息
接下来m行每行n个字符,第i行描述矩阵某一列的信息

输出描述

输出一个字符矩阵表示字典序最小的矩阵

示例1

输入:

2 3
10?
?11
01
10
1?

输出:

101
011

示例2

输入:

3 1
0
?
1
0?1

输出:

0
0
1

示例3

输入:

2 2
10
01
10
01

输出:

10
01

示例4

输入:

4 3
??0
11?
?01
1?1
1???
?111
0?1?

输出:

010
110
101
101

原站题解

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

C++ 解法, 执行用时: 124ms, 内存消耗: 680K, 提交时间: 2021-09-06 18:09:31

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int n,m;
vector<int> ve[36];
int match[36];
bool vis[36];
char ch[36][36];
string s[36];
bool find(int x)
{
	for(auto i:ve[x])
	{
		if(vis[i])continue;
		vis[i]=1;
		if(!match[i]||find(match[i]))
		{
			match[i]=x;
			return 1;
		}
	}
	return 0;
}
void build()
{
	for(int i=1;i<=m;++i)ve[i].clear();
	for(int i=1;i<=m;++i)
	{
		for(int j=1;j<=m;++j)
		{
			int flag=1;
			for(int k=1;k<=n;++k)
			{
				if(ch[k][i]!='?'&&s[j][k-1]!='?'&&ch[k][i]!=s[j][k-1])
				{
//					cout<<i<<' '<<j<<' '<<ch[k][i]<<' '<<s[j][k-1]<<"a\n"; 
					flag=0;
					break;
				}
			}
			if(flag)
			{
//				cout<<i<<' '<<j<<"a\n";
				ve[i].push_back(j);
			}
		}
	}
}
int check()
{
	int js=0;
	memset(match,0,sizeof match);
	for(int i=1;i<=m;++i)
	{
		memset(vis,0,sizeof vis);
		if(find(i))js++;
	}
	return js;
}
int main()
{
	ios;
	cin>>n>>m;
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=m;++j)
		{
			cin>>ch[i][j];
		}
	}
	for(int i=1;i<=m;++i)cin>>s[i];
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=m;++j)
		{
			if(ch[i][j]=='?')
			{
				ch[i][j]='0';
			}
			build();
			if(check()!=m)ch[i][j]='1';
		}
	}
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=m;++j)
		{
			cout<<ch[i][j];
		}
		cout<<'\n';
	}
}

C++14(g++5.4) 解法, 执行用时: 76ms, 内存消耗: 632K, 提交时间: 2020-06-09 13:29:01

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 30
#define P(x,y) (((x)-1)*m+(y))
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
using namespace std;
int n,m,a[N+5][N+5],b[N+5][N+5],ee,lnk[N+5],vis[N+5],s[N+5];struct edge {int to,nxt;}e[N*N+5];
I bool Match(CI x,CI ti)
{
	RI i;for(i=lnk[x];i;i=e[i].nxt)
	{
		if(vis[e[i].to]==ti) continue;vis[e[i].to]=ti;
		if(!s[e[i].to]||Match(s[e[i].to],ti)) return s[e[i].to]=x,1;
	}return 0;
}
I bool Check()
{
	RI i,j;for(ee=0,i=1;i<=m;++i) lnk[i]=vis[i]=s[i]=0;
	RI k;for(i=1;i<=m;++i) for(j=1;j<=m;++j)
		{for(k=1;k<=n&&(!~a[k][i]||!~b[j][k]||a[k][i]==b[j][k]);++k);k>n&&add(i,j);}
	for(i=1;i<=m;++i) if(!Match(i,i)) return 0;return 1;
}
int main()
{
	RI i,j;char op;scanf("%d%d",&n,&m);
	for(i=1;i<=n;++i) for(j=1;j<=m;++j) cin>>op,a[i][j]=(op=='?'?-1:(op&1));
	for(i=1;i<=m;++i) for(j=1;j<=n;++j) cin>>op,b[i][j]=(op=='?'?-1:(op&1));
	for(i=1;i<=n;++i) for(j=1;j<=m;++j) !~a[i][j]&&(a[i][j]=0,!Check()&&(a[i][j]=1));
	for(i=1;i<=n;++i,putchar('\n')) for(j=1;j<=m;++j) putchar(a[i][j]+48);return 0;
}

上一题