zoukankan      html  css  js  c++  java
  • 膜法记录消除行列(二进制枚举)

    链接: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
    ");
            }
        }
    }
  • 相关阅读:
    C#控件开发(三)
    C#控件开发(四)
    如何将方行的按纽改变为其他的形状
    C#绘制圆角矩形
    Win7右键不能新建文件夹
    WinForm窗体FormClosing事件导致无法关机
    反射动态调用WinForm窗口
    C#钩子本线程内消息拦截
    C#控件开发(一)
    七个C#编程小技巧
  • 原文地址:https://www.cnblogs.com/lipu123/p/14257093.html
Copyright © 2011-2022 走看看