黑白矩阵 题解
1<=n,m<=100,1<=k<=10,T<=50
首先这个同色极大连通块都是矩形说明了啥呢?
相邻两行(两列)一定是同色或者反色的。
当n>k时,我们可以发现有一行肯定是不会被修改的,我们枚举那一行统计一下即可。
否则n<=10,那么我们枚举修改完之后某一列的状态,2^n枚举就行了。
这真是一道**题啊。
(下面这段代码的cnt1比较不和谐,可能要修改一下)
#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <string> #include <bitset> #include <vector> #include <set> #include <map> #include <queue> #include <algorithm> #include <sstream> #include <stack> #include <iomanip> using namespace std; #define pb push_back #define mp make_pair #define pii pair<int,int> #define ll long long #define ld double #define vi vector<int> #define fi first #define se second #define fe first #define cnt1 __builtin_popcount int T,n,m,k; int arr[233][233],orz[233]; bitset<103> bs[233],fbs[233]; void sol() { scanf("%d%d%d",&n,&m,&k); for(int i=0;i<n;i++) bs[i]=bitset<103>(); for(int i=0;i<n;i++) fbs[i]=bitset<103>(); for(int j=0;j<m;j++) orz[j]=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) scanf("%d",&arr[i][j]), bs[i][j]=arr[i][j], fbs[i][j]=!arr[i][j] , orz[j]=orz[j]*2+arr[i][j]; } //乱搞 if(n>k) { int ans=2000000000; for(int i=0;i<n;i++) { int cnt=0; for(int j=0;j<n;j++) cnt+=min((bs[i]^bs[j]).count(),(bs[i]^fbs[j]).count()); ans=min(ans,cnt); } if(ans>k) puts("-1"); else printf("%d\n",ans); return; } int ans=2000000000; for(int i=0;i<(1<<n);i++) { int cnt=0; for(int j=0;j<m;j++) cnt+=min(cnt1(orz[j]^i),cnt1(orz[j]^i^((1<<n)-1))); ans=min(ans,cnt); } if(ans>k) puts("-1"); else printf("%d\n",ans); } #define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);} int main() { FO(table) scanf("%d",&T); while(T--) sol(); }