膜法记录

膜法记录

https://ac.nowcoder.com/acm/problem/204415

枚举优化

题意:

牛牛最近在玩一款叫做《膜法记录》的游戏,这个游戏的机制是这样的:
在一局游戏中,所有的敌人都排布在一个 {n}n 行 {m}m 列的网格中,牛牛指挥着他的魔法少女对敌人进行攻击。
攻击有两种类型:行blast,列blast
行blast能消灭一整行的敌人,列blast能消灭一整列的敌人
牛牛总共能够释放 {a}a 次行blast,{b}b 次列blast
给定某局游戏的初始局面,请问牛牛能否将敌人全歼?
输入描述:
第一行包含一个正整数{T}T,表示测试数据组数,接下来是{T}T组测试数据
每组测试数据的第一行有四个正整数 {n}n,{m}m,{a}a,{b}b
接下来有{n}n行,每行是一个长度为{m}m的字符串,第{i}i行第{j}j列的字符如果是*则说明这里有一个敌人,如果是.说明这里没有
输出描述:
对每组测试数据输出一行,如果能消灭所有的敌人,就输出yes,否则输出no

分析:

因为n很小,所以我们可以很容易的想到枚举我们动用魔法的行
然后在判断此刻还有多少列仍有敌人
如果仍有敌人的量小于等于b那么我们就成功可以消灭全部敌人了!

但是,困难便在于如何进行枚举。
我看了人家的题解后会了。
我们可以用一个零一串表示有哪些行被消除了,有哪些没被消除
如0101110
则第0行没消,第1行消了,第2行消了。。。。。。
既然是零一串,那么我们就可以用一个数字去存这个零一串
int长度32远大于20,所以我们可以用一个int来进行枚举。
每次改变行的选取也只需要+1就可以了十分方便。

for (int i=0;i<(1<<n);i++)

但是,然后我们要有一个剪枝,因为我们可能出现这个零一串中a的数量并没有a个,即我们并没有使用a次魔法这种时候是不用判断的
另外,当1的数量超过ashi我们也是不用判断的
我们只要判断使用了a次魔法后的情况就可以了。

接下来是判断在进行了a次魔法后,仍有敌人的列数
我们遍历每一列j
然后遍历这一列的每一行i
如果这一行没有被消除即(cur>>i)&1 == 1 cur为零一串
并且此处是敌人in[i][j] = '*'
那么这一列就仍有敌人cnt++;break。看下一列

代码如下,面向结果编程

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int max_n = 30;
string s[max_n];
int t, n, m, a, b;

int main() {
    ios::sync_with_stdio(0);
    cin >> t;
    while (t--) 
    {
        cin >> n >> m >> a >> b;
        for (int i = 0;i < n;i++)cin >> s[i];
        int cur = 0;
        for (cur = 0;cur < (1 << n);cur++)
        {
            int cnt = 0;
            for (int i = 0;i < n;i++)
                if ((cur >> i) & 1)cnt++;
            if (cnt != a)continue;

            cnt = 0;
            for (int i = 0;i < m;i++)
            {
                for (int j = 0;j < n;j++)
                {
                    if (!((cur >> j) & 1) && s[j][i] == '*')
                    {
                        cnt++;break;
                    }
                }
            }
            if (cnt <= b)break;
        }
        if (cur < (1 << n))cout << "yes\n";
        else cout << "no\n";
    }
}
全部评论

相关推荐

06-25 09:33
厦门大学 Java
球球别拷打俺了:现在日常估计没啥hc了,等到八月多估计就慢慢有了。双九✌🏻不用焦虑的
投递快手等公司10个岗位
点赞 评论 收藏
分享
Twilight_m...:表格简历有点难绷。说说个人看法: 1.个人基本情况里好多无意义信息,什么婚姻状况、健康状况、兴趣爱好、户口所在地、身份证号码、邮政编码,不知道的以为你填什么申请表呢。 2.校内实践个人认为对找工作几乎没帮助,建议换成和测开有关的项目,实在没得写留着也行。 3.工作经历完全看不出来是干什么的,起码看着和计算机没啥关系,建议加强描述,写点你在工作期间的实际产出、解决了什么问题。 4.个人简述大而空,看着像AI生成,感觉问题最大。“Python,C,C++成为我打造高效稳定服务的得力工具”、“我渴望凭借自身技术知识与创新能力,推动人工智能技术的应用发展,助力社会实现智能化转型”有种小学作文的美感。而且你确定你个人简述里写的你都会嘛?你AI这块写的什么“深入研究”,发几篇顶会的硕博生都不一定敢这么写。而且你AI这块的能力和软测也完全无关啊。个人简述建议写你对哪些技术栈、哪些语言、哪些生产工具的掌握,写的有条理些,而且最好是和测开强相关的。
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务