A binary matrix is called good if every even length square sub-matrix has an odd number of ones.
Given a binary matrix aa consisting of nn rows and mm columns, determine the minimum number of cells you need to change to make it good, or report that there is no way to make it good at all.
All the terms above have their usual meanings — refer to the Notes section for their formal definitions.
Input
The first line of input contains two integers nn and mm (1≤n≤m≤1e6 and n⋅m≤1e6) — the number of rows and columns in a, respectively.
The following nn lines each contain mm characters, each of which is one of 0 and 1. If the jj-th character on the ii-th line is 1, then ai,j=1. Similarly, if the jj-th character on the ii-th line is 0, then ai,j=0.
Output
Output the minimum number of cells you need to change to make aa good, or output −1 if it's not possible at all.
Examples
input
3 3 101 001 110
output
2
input
7 15 000100001010010 100111010110001 101101111100100 010000111111010 111010010100001 000011001111101 111111011010011
output
-1
Note
In the first case, changing a1,1 to 00 and a2,2 to 11 is enough.
You can verify that there is no way to make the matrix in the second case good.
Some definitions —
思路:首先发现当n和m都大于3时,无解,因此在有解的情况中n必定小于4,我们可以考虑状压dp,枚举i和i-1列的合法状态。
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast","inline")
#include
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,b,a) for(int i=b;i>=a;i--)
#define Mst(a,b) memset(a,b,sizeof(a))
#define fir first
#define se second
#define PII pair
#define lowbit(x) x&-x
const int N = 1e6+5;
int n,m;
int g[10][10],dp[N][10],s[N];
string str[N];
int get(int x,int y) {
int cnt = 0;
rep(i,0,2) {
cnt += ((x>>i&1)^(y>>i&1));
}
return cnt;
}
bool check(int x,int y) {//判断是否合法
if(m <= 1) return true;
if(m <= 2) {
int cnt = 0;
rep(i,0,1) {
cnt += (x>>i)&1;
cnt += (y>>i)&1;
}
return cnt&1;
}
int cnt1 = 0,cnt2 = 0;
rep(i,0,1) {
cnt1 += (x>>i)&1;
cnt1 += (y>>i)&1;
}
rep(i,1,2) {
cnt2 += (x>>i)&1;
cnt2 += (y>>i)&1;
}
return ((cnt1&1)&&(cnt2&1));
}
int main() {
cin >> n >> m;
rep(i,0,n-1) cin >> str[i];
if(n == 1 || m == 1) {
cout << "0" << endl;
return 0;
}
if(n >= 4 && m >= 4) cout << "-1" << endl;
else {
swap(n,m);
rep(i,0,n-1) {
int cnt = 0;
rep(j,0,m-1) {
cnt = cnt * 2 + (str[j][i] == '1');
}
s[i] = cnt;
}
for(int i=0;i<1<