LibreOJ #6030.「雅礼集训 2017 Day1」矩阵 乱搞

解决矩阵问题,通过最少操作次数将n*n的01矩阵变为全1。首先选择一行变为全1,然后依次将非全1列转换。枚举行,计算使特定行全1的最小代价,最终取最小代价作为答案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

现在有一个n*n的01矩阵,现在每次可以把某一列替换成某一行,问最少操作次数使得整个矩阵都是1。
n1000n≤1000

分析

把矩阵变成全1显然只能先把某一行变成全1,然后再把所有不是全1的列变成全1。
那么我们枚举每一行,然后求先把这行变成全1的最小代价。
而要把这行变成全1,设这是第x行,就要每次选择某一行满足其第x列是1,然后来填充第x行的0。
若不存在某行的第x列是1,我们也可以通过先操作一次使得某行的第x列是1。
然后取个最小值就是答案。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

const int N=1005;
const int inf=1000000000;

int n,c[N];
bool a[N][N],vis[N];
char str[N];

int main()
{
    scanf("%d",&n);
    int flag=inf;
    for (int i=1;i<=n;i++)
    {
        scanf("%s",str+1);
        for (int j=1;j<=n;j++)
            if (str[j]=='#') a[i][j]=1,vis[j]=1,c[j]++,flag=1;
            else a[i][j]=0;
    }
    int ret=n,ans=inf;
    for (int i=1;i<=n;i++) if (c[i]==n) ret--;
    for (int i=1;i<=n;i++)
    {
        int s=0;
        for (int j=1;j<=n;j++)
            if (!a[i][j]) s++;
        ans=std::min(ans,s+ret+(!vis[i]?flag:0));
    }
    if (ans==inf) ans=-1;
    printf("%d",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值