【牛客小白月賽23 A】膜法記錄 (二進制枚舉)

【題目傳送門】

題目描述:

牛牛最近在玩一款叫做《膜法記錄》的遊戲,這個遊戲的機制是這樣的: 在一局遊戲中,所有的敵人都排布在一個 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~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章