題目描述:
牛牛最近在玩一款叫做《膜法記錄》的遊戲,這個遊戲的機制是這樣的: 在一局遊戲中,所有的敵人都排布在一個 n{n}n 行 m{m}m 列的網格中,牛牛指揮着他的魔法少女對敵人進行攻擊。 攻擊有兩種類型:行blast,列blast 行blast能消滅一整行的敵人,列blast能消滅一整列的敵人 牛牛總共能夠釋放 a{a}a 次行blast,b{b}b 次列blast 給定某局遊戲的初始局面,請問牛牛能否將敵人全殲?
輸入描述:
第一行包含一個正整數T,表示測試數據組數,接下來是T組測試數據每組測試數據的第一行有四個正整數 n,m,a,b接下來有n{n}n行,每行是一個長度爲m的字符串,第i行第j列的字符如果是 * 則說明這裏有一個敵人,如果是 . 說明這裏沒有
輸出描述:
對每組測試數據輸出一行,如果能消滅所有的敵人,就輸出yes,否則輸出no
說明
第一個樣例,我可以在第一行放一個行blast,然後前兩列都放一個列blast,就把敵人給全殲了。第二個樣例,我不管怎麼安排攻擊策略,都沒法全殲敵人
備註:
分析:
這道題的n很小,只有20,我們可以利用二進制數來枚舉可操作的行,我們可以認爲1是對行操作,0是不操作;比如n=4時,若對3,4行操作對應的二進制數表示爲1100。
由此我們對 0到2^n-1 (0表示都不操作,2^n-1表示的二進制數每一位都爲1,即表示對n行都操作)範圍內的數進行遍歷,即枚舉各種可操作行的組合。
然後再對整個矩陣進行遍歷,選出來沒有被行操作過得敵人,讓列進行操作,如果 列操作 的次數小於題目中給定的次數,即滿足,反之不滿足。
代碼如下:
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+100;
string s[N];//字符串數組
int main() {
int n,m,a,b,t;
int flag;
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++)//枚舉0-2^n-1範圍內的數,即枚舉各種組合;
{
int x=0;
for(int j=0;j<n;j++)
if((i>>j)&1) x++;//判斷有幾個位有1,即對 幾行 操作
if(x!=a) continue;
int y=0;
for(int j=0;j<m;j++)
for(int k=0;k<n;k++)
if(s[k][j]=='*'&&!((i>>k)&1))//判斷一下這個行有沒有操作過,如果行操作過,就不用列操作了
{
y++;
break;//這一列消滅完了,就跳出這一列到下一列;
}
if(y<=b) flag=1;
}
if(flag) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
six day~