返回顶部

AtCoder Beginner Contest 173 C - H and V (二进制枚举)

  • 题意:有一张图,.表示白色,#表示黑色,每次可以将多行和多列涂成红色(也可不涂),问有多少种方案,使得剩下黑点的个数为\(k\).

  • 题解:又学到了新的算法qwq,因为这题的数据范围很小,所以可以用二进制枚举来将所以情况枚举出来.

    关于二进制枚举:对于一个集合\(n\),有\(2^n\)个子集,而\([0,2^n]\),我们可以用\(n\)的二进制来表示,对于每一位,如果该位是\(1\),就表示选,所以我们先确定某种情况,然后再去遍历每一位,就能将\(2^n\)的每种情况枚举出来.

    对于这题,我们枚举所有行和列的选择情况,然后确定有多少黑点被涂成了红色,判断是否等于\(sum-k\)即可.

  • 代码:

    int n,m,k;
    char a[10][10];
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);
      	cin>>n>>m>>k;
      	int sum=0;
      	for(int i=0;i<n;++i){
      		for(int j=0;j<m;++j){
      			cin>>a[i][j];
      			if(a[i][j]=='#') sum++;
      		}
      	}
    
      	int cnt=0;
      	int ans=0;
      	 for(int i=0;i<(1<<n);++i){
      	 	for(int j=0;j<(1<<m);++j){
      	 		cnt=0;
      	 		for(int r=0;r<n;++r){
      	 			for(int c=0;c<m;++c){
      	 				if( ((i&(1<<r)) || (j&(1<<c)))&& a[r][c]=='#') cnt++;
      	 			} 
      	 		}
      	 		if(cnt==sum-k) ans++;
      	 	}
      	 }
    
      	 cout<<ans<<endl;
    
        return 0;
    }
    
posted @ 2020-07-07 10:53  _Kolibri  阅读(504)  评论(0)    收藏  举报