20211211解题报告

2、刷颜色(brush.cpp)
【题目描述】
        我们有一个 H 行 W 列的矩阵方格(1≤H,W≤6)行号是从上往下编号,列号是从左往右
编号。
        第 i 行第 j 列位置小方格的颜色用字符 Ci,j 给出(1≤i≤H;1≤j≤W;Ci,j . # ):
        ⚫ 如果 Ci,j为字符 . ,则该小方格为白色;
        ⚫ 如果 C i,j 为字符 # ,则该小方格为黑色;
        考虑执行以下操作:
        •选择多行(也可能不选行)和多列(也可能不选列),然后将所选行中的所有格子和所
选列中的所有格子都涂成红色。
        给你一个正整数 K(1≤K≤H×W),问你有多少次不同的选择,会导致每个选择的操作
结果都只剩下 K 个黑色方格?
【输入格式】brush.in
        第 1 行输入三个正整数 H、W 和 K。
        接下来是一个 H 行、W 列的矩阵,每个位置用 ’ . # 表示相应的颜色。
【输出格式】brush.out
        输出一个整数,表示满足条件的行和列的选择次数。
        如果输入数据本身就满足条件,并且不能做任何选择(选择了就不满足),则输出 1;如
果无法满足剩下 K 个黑色方格,则输出 0。
【输入输出样例 1】
brush.in                         brush.out
2 3 2                                5
..#
###
 
【算法分析】
        题意:有一张图,“.”表示白色,“#”表示黑色,每次可以将多行和多列涂成红色
(也可不涂),问有多少种方案,使得剩下黑点的个数为 k。
        可以用二进制枚举(即状态压缩)来将所以情况枚举出来:
        对于一个有 N 个元素的集合,共有 2的N次方 个子集,而对于[0,2^ N ],我们可以用 N 的二进制来表示,对于每一位,如果该位是 1,就表示选择了。
        于是我们枚举所有行和列的选择方案,然后再枚举每个方案有多少黑点被涂成了红色:
        我们可以先枚举某种选择的情况,然后再去遍历每一个位置,判断该位置是否为黑色
#,如是则刷掉这个黑色(cnt++,cnt 是刷掉的#数量)。
        设初始的#数量为 sum,则如果某个枚举的方案出现 sum-cnt=k 的情况,则答案
ans++;
【考点】
        状态压缩,模拟。
【代码如下】:
#include<bits/stdc++.h>
using namespace std;
int n,m,k,sum=0,cnt,ans=0;
char a[10][10];
int main(){
cin>>n>>m>>k;
for(int i=0;i<n;++i)
{
    for(int j=0;j<m;++j)
    {
        cin>>a[i][j];
        if(a[i][j]=='#') sum++;
    } 
}
for(int i=0;i<(1<<n);++i) //枚举行的选择情况
{
    for(int j=0;j<(1<<m);++j) //枚列的选择情况
    {
        cnt=0;
        for(int r=0;r<n;++r) //枚举某个位置的行
            for(int c=0;c<m;++c) //枚举某个位置的列
                if(((i&(1<<r)) || (j&(1<<c))) && a[r][c]=='#') cnt++;
        if(sum-cnt==k) ans++; //如果位置(r,c)被行或列选择则,被刷掉
    } //剩下 k 个黑子则次方案满足条件
}
    cout<<ans<<endl;
    return 0;
}
【总结】对于此类看起来数据很小,但又可能出现指数级情况且每种情况只有两种可能,通常使用·状态压缩
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值