Problem:
Score : 1000 points

Problem Statement

You have two strings A = A_1 A_2 ... A_n and B = B_1 B_2 ... B_n of the same length consisting of 0 and 1.

You can transform A using the following operations in any order and as many times as you want:

Shift A by one character to the left (i.e., if A = A_1 A_2 ... A_n, replace A with A_2 A_3 ... A_n A_1).

Shift A by one character to the right (i.e., if A = A_1 A_2 ... A_n, replace A with A_n A_1 A_2 ... A_{n-1}).

Choose any i such that B_i = 1. Flip A_i (i.e., set A_i = 1 - A_i).

You goal is to make strings A and B equal.

Print the smallest number of operations required to achieve this, or -1 if the goal is unreachable.

Constraints

1 \leq |A| = |B| \leq 2,000

A and B consist of 0 and 1.

Input

Input is given from Standard Input in the following format:

A
B

Output

Print the smallest number of operations required to make strings A and B equal, or -1 if the goal is unreachable.

Sample Input 1

1010
1100

Sample Output 1

3

Here is one fastest way to achieve the goal:

Flip A_1: A = 0010

Shift A to the left: A = 0100

Flip A_1 again: A = 1100

Sample Input 2

1
0

Sample Output 2

-1

There is no way to flip the only bit in A.

Sample Input 3

11010
10001

Sample Output 3

4

Here is one fastest way to achieve the goal:

Shift A to the right: A = 01101

Flip A_5: A = 01100

Shift A to the left: A = 11000

Shift A to the left again: A = 10001

Sample Input 4

0100100
1111111

Sample Output 4

5

Flip A_1, A_3, A_4, A_6 and A_7 in any order.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include "bits/stdc++.h"
using namespace std;
const int N = 2e3 + 3;
int n;
char a[N];
char b[N];
int ones[N];
int zeroes[N];
int changes[N];
int siz;
int lft[N];
int rgt[N];
int get(int l , int r){
	if(l == 0){
		return ones[r];
	}
	if(l <= r){
		return ones[r] - ones[l - 1];
	}
	return ones[n - 1] - ones[l - 1] + ones[r];
}
int moveleft[N];
int moveright[N];
pair < int , int > arr1[N];
pair < int , int > arr2[N];
int idx1[N];
int idx2[N];
bool done[N];
int ans;
int solveright(int move){
	int res = 0;
	siz = 0;
	for(int i = 0 ; i < n ; ++i){
		int who = (i + n - move) % n;
		if(a[who] != b[i]){
			if(!get(who , i)){
				changes[++siz] = i;
			}
			++res;
		}
	}
	if(!siz){
		return res;
	}
	for(int i = 1 ; i <= siz ; ++i){
		int idx = changes[i];
		if(rgt[idx] == n){
			moveright[i] = n - idx + rgt[0];
		}
		else{
			moveright[i] = rgt[idx] - idx;
		}
		int l = (idx - move + n) % n;
		if(lft[l] == -1){
			moveleft[i] = l + n - lft[n - 1];
		}
		else{
			moveleft[i] = l - lft[l];
		}
	}
	for(int i = 1 ; i <= siz ; ++i){
		arr1[i] = make_pair(moveleft[i] * 2 , i);
		arr2[i] = make_pair(moveright[i] * 2 , i);
	}
	sort(arr1 + 1 , arr1 + 1 + siz);
	sort(arr2 + 1 , arr2 + 1 + siz);
	for(int i = 1 ; i <= siz ; ++i){
		idx1[arr1[i].second] = i;
		idx2[arr2[i].second] = i;
		done[i] = 0;
	}
	done[0] = 0;
	int ptr = siz;
	int add = 1e9;
	add = min(add , arr2[siz].first);
	arr2[0].first = 0;
	for(int i = 1 ; i <= siz ; ++i){
		done[idx2[arr1[i].second]] = 1;
		while(done[ptr]){
			--ptr;
		}
		add = min(add , arr1[i].first + arr2[ptr].first);
	}
	return res + add;
}
int solveleft(int move){
	int res = 0;
	siz = 0;
	for(int i = 0 ; i < n ; ++i){
		int who = (i + move) % n;
		if(a[who] != b[i]){
			if(!get(i , who)){
				changes[++siz] = who;
			}
			++res;
		}
	}
	if(!siz){
		return res;
	}
	for(int i = 1 ; i <= siz ; ++i){
		int idx = changes[i];
		if(rgt[idx] == n){
			moveright[i] = n - idx + rgt[0];
		}
		else{
			moveright[i] = rgt[idx] - idx;
		}
		int l = (idx - move + n) % n;
		if(lft[l] == -1){
			moveleft[i] = l + n - lft[n - 1];
		}
		else{
			moveleft[i] = l - lft[l];
		}
	}
	for(int i = 1 ; i <= siz ; ++i){
		arr1[i] = make_pair(moveleft[i] * 2 , i);
		arr2[i] = make_pair(moveright[i] * 2 , i);
	}
	sort(arr1 + 1 , arr1 + 1 + siz);
	sort(arr2 + 1 , arr2 + 1 + siz);
	for(int i = 1 ; i <= siz ; ++i){
		idx1[arr1[i].second] = i;
		idx2[arr2[i].second] = i;
		done[i] = 0;
	}
	done[0] = 0;
	int ptr = siz;
	int add = 1e9;
	add = min(add , arr2[siz].first);
	arr2[0].first = 0;
	for(int i = 1 ; i <= siz ; ++i){
		done[idx2[arr1[i].second]] = 1;
		while(done[ptr]){
			--ptr;
		}
		add = min(add , arr1[i].first + arr2[ptr].first);
	}
	return res + add;
}

int main(){
	scanf("%s" , a);
	scanf("%s" , b);
	n = strlen(a);
	ones[0] = b[0] == '1';
	zeroes[0] = b[0] == '0';
	bool rip = a[0] == '1';
	for(int i = 1 ; i < n ; ++i){
		ones[i] = ones[i - 1] + (b[i] == '1');
		zeroes[i] = zeroes[i - 1] + (b[i] == '0');
		rip |= a[i] == '1';
	}
	if(rip && ones[n - 1] == 0){
		printf("-1\n");
		return 0;
	}
	if(b[0] == '1'){
		lft[0] = 0;
	}
	else{
		lft[0] = -1;
	}
	for(int i = 1 ; i < n ; ++i){
		if(b[i] == '1'){
			lft[i] = i;
		}
		else{
			lft[i] = lft[i - 1];
		}
	}
	rgt[n] = n;
	for(int i = n - 1 ; i >= 0 ; --i){
		if(b[i] == '1'){
			rgt[i] = i;
		}
		else{
			rgt[i] = rgt[i + 1];
		}
	}
	ans = 1e9;
	for(int i = 0 ; i < n ; ++i){
		ans = min(ans , solveleft(i) + i);
	}
	for(int i = 1 ; i < n ; ++i){
		ans = min(ans , solveright(i) + i);
	}
	printf("%d\n" , ans);
}