膜法記錄(二進制枚舉)

傳送門

題目描述

牛牛最近在玩一款叫做《膜法記錄》的遊戲,這個遊戲的機制是這樣的:
在一局遊戲中,所有的敵人都排布在一個 n 行 m 列的網格中,牛牛指揮着他的魔法少女對敵人進行攻擊。
攻擊有兩種類型:行blast,列blast
行blast能消滅一整行的敵人,列blast能消滅一整列的敵人
牛牛總共能夠釋放 a 次行blast,b 次列blast
給定某局遊戲的初始局面,請問牛牛能否將敵人全殲?

輸入描述:
第一行包含一個正整數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,就把敵人給全殲了。第二個樣例,我不管怎麼安排攻擊策略,都沒法全殲敵人

思路:i用二進制表示,0表示此行不使用,1表示使用,所以0-(2^n-1)可以枚舉出所有的情況(每一行是否使用消滅行線滅操作),i右移j位來找到i中有幾個1,如果1的個數和a相等,然後遍歷矩陣,如果(k,j)這個格子滿足:第k行沒有使用行消滅,該格子有敵人,就需要執行列消滅,所以c++,遍歷結束之後,c<=b輸出"yes"

AC代碼

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+100;
const int inf=0x3f3f3f3f;
string s[maxn];
int main()
{
     int n,m,a,b,flag=0,t;
     cin>>t;
     while(t--)
     {
         flag=0;
     cin>>n>>m>>a>>b;
     for(int i=0;i<n;i++)
     cin>>s[i];
     for(int i=0;i<(1<<n);i++)//0001 0010 0011 0100.........
     {
         int r=0;
         for(int j=0;j<n;j++)
         if((i>>j)&1)r++;

         if(r!=a)continue;
         int c=0;
         for(int j=0;j<m;j++)
         for(int k=0;k<n;k++)
         if(s[k][j]=='*'&&!((i>>k)&1))
         {
             c++;
             break;
         }
       if(c<=b)flag=1;
         
     }
     if(flag)cout<<"yes"<<endl;
     else cout<<"no"<<endl;
     }
     system("pause");
     return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章