膜法记录消除行列(二进制枚举)

链接:https://ac.nowcoder.com/acm/contest/4784/A
来源:牛客网

牛牛最近在玩一款叫做《膜法记录》的游戏,这个游戏的机制是这样的:
在一局游戏中,所有的敌人都排布在一个 n 行 m 列的网格中,牛牛指挥着他的魔法少女对敌人进行攻击。
攻击有两种类型:行blast,列blast
行blast能消灭一整行的敌人,列blast能消灭一整列的敌人
牛牛总共能够释放 a 次行blast,b 次列blast
给定某局游戏的初始局面,请问牛牛能否将敌人全歼?

输入描述:

第一行包含一个正整数T{T}T,表示测试数据组数,接下来是T{T}T组测试数据
每组测试数据的第一行有四个正整数 n,m,a,b
接下来有n行,每行是一个长度为m的字符串,第i行第j列的字符如果是*则说明这里有一个敌人,如果是.说明这里没有

输出描述:

对每组测试数据输出一行,如果能消灭所有的敌人,就输出yes,否则输出no
示例1

输入

复制
2
3 3 1 2
..*
.*.
*..
4 4 3 1
..**
**..
.**.
*.**

输出

复制
yes
no

说明

第一个样例,我可以在第一行放一个行blast,然后前两列都放一个列blast,就把敌人给全歼了。第二个样例,我不管怎么安排攻击策略,都没法全歼敌人

备注:

 题目大意:

就是你有a次行操作(可以消灭一行中的敌人)和b次列操作(可以消灭一列中的敌人),

问就是在a次行操作和b次列操作后,是否可以把n行m列的敌人全消灭掉

思路:

可以看到n的范围很小,可以二进制枚举行,让他正好消灭a行然后再判断列是否满足条件

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+100;
int t;
int n,m,a,b;
char mp[100][maxn];
int main(){
    cin>>t;
    while(t--){
        cin>>n>>m>>a>>b;
        for(int i=0;i<n;i++){
            scanf("%s",mp[i]);
        }
        int ok=0;
        for(int i=0;i<(1<<n);i++){//枚举行 
            int cnt=0;
            for(int j=0;j<n;j++){
                if((i>>j)&1){
                    cnt++;
                }
            }
            if(cnt!=a){//如果有其他的可以那么都用完a行也能用完 
                continue;
            }
            int x=0;
            for(int j=0;j<m;j++){//枚举这一列行经过行操作还有没有敌人 
                int flag=0;
                for(int k=0;k<n;k++){
                    if(!((i>>k)&1) && mp[k][j]=='*'){//有敌人 
                        flag=1;
                        break;
                    }
                }
                if(flag){
                    x++;
                }
                
            }
            if(x<=b){
                ok=1;
                break;
            } 
        } 
        if(ok){
            cout<<"yes"<<endl;
        } 
        else{
            cout<<"no"<<endl;
        }
    }
} 

dfs:

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<set>
using namespace std;
int t,n,m,a,b,i,j,flag;
char s[6][100005];
int vis[6];
int judge(){
    set<int>q;
    for(i=0;i<n;i++){
        if(vis[i])  continue;
        else{
            for(j=0;j<m;j++){
                if(s[i][j]=='*'){
                    q.insert(j);
                }
            }
        }
    }
    return q.size()<=b;
}
void dfs(int num,int aa){
    if(judge()){
        flag=1;
        return;
    }
    if(num>=n || aa>=a || flag){
        return;
    }
    
    vis[num]=1;
    dfs(num+1,aa+1);
    vis[num]=0;
    dfs(num+1,aa);
}   
int main()
{   
    scanf("%d",&t);
    while(t--){
        memset(vis,0,sizeof(vis));
        memset(s,'',sizeof(s));
        scanf("%d%d%d%d",&n,&m,&a,&b);
        flag=0;
        for(i=0;i<n;i++){
            scanf("%s",s[i]);
        }
        dfs(0,0);
        if(flag){
            printf("yes
");
        }
        else{
            printf("no
");
        }
    }
}
原文地址:https://www.cnblogs.com/lipu123/p/14257093.html