http://codeforces.com/group/NVaJtLaLjS/contest/241861/problem/B
Felipe has a binary string A of length n (1 ≤ n ≤ 5000) which he wants to transform into string B (of length n as well) using a series of operations. He can use the following operations:
-
Operation 1: He can move the last element of A to the front. For example, 01001 would become 10100.
-
Operation 2: He can take any two consecutive elements and flip them. A flip turns a 1 into a 0 and a 0 into a 1. For example, if he applies this operation to the first two elements of 10100, it would become 01100.
Felipe actually doesn’t like operation 2, so he wants to use it as few times as possible. Given A and B find the minimum number of operations type 2 needed to transform A into B, or say if it’s impossible.
Input
Input consist of two lines with binary strings A and B, respectively.
It is guaranteed that both strings have the same length.
Output
Print one single line with the minimum number of operations type 2 needed to transform A into B. or - 1 if it’s impossible to do so.
Examples
inputCopy
01001
01010
outputCopy
0
inputCopy
11111
00000
outputCopy
-1
inputCopy
001010
100001
outputCopy
1
题意:有等长的两字符串s,t。由两个操作来把s变成t,①把s的最后一个字符移到最前面②选出两个相邻的字符,每个字符取反。要求尽量少用操作2。
思路:考虑操作1,它的作用是什么?有两个作用,一是循环移位,把s变到一个理想的姿势,从而尽量少用操作2然后与t相同,二是使得s的首末字符可以使用操作2。
那么我们把s扩大一倍,即ss,枚举每相邻的n个字符,然后暴力匹配,只要当前s[i],t[i]不一样就使用操作2,如果最后一个字符相同,那么可行,与ans比较,取最小值。 因为这个过程中漏掉了【首末字符可以取反】,所以把首末字符取反再做一遍
因为操作1只有那两个用处,所以说,如果存在移位->取反->移位->取反->移位…这样的操作,实际上,只要突出理想姿势+首末可以取反就可以了。
实际上我自己也还是不大理解
#include<bits/stdc++.h>
using namespace std;
#define maxn 10000+100
int n,ans=(1<<30);
char s[maxn],t[maxn];
void check(char *s,int flip)
{
int ret=flip;
for(int i=0;i<n-1;i++)
{
if(s[i]!=t[i])ret++,s[i]='1'-(s[i]-'0'),s[i+1]='1'-(s[i+1]-'0');
}
if(s[n-1]==t[n-1])ans=min(ans,ret);
}
int main()
{
//freopen("input.in","r",stdin);
scanf("%s%s",s,t);
n=strlen(s);
int num1=0,num2=0;
for(int i=0;i<n;i++)num1+=s[i]-'0',num2+=t[i]-'0';
if(abs(num1-num2)&1){cout<<-1<<endl;exit(0);}
for(int i=0;i<n;i++)s[i+n]=s[i];
for(int i=0;i<n;i++)
{
char b[maxn];
memcpy(b,s+i,sizeof(char)*n);
check(b,0);
memcpy(b,s+i,sizeof(char)*n);
b[0]='1'-(b[0]-'0');b[n-1]='1'-(b[n-1]-'0');
check(b,1);
}
cout<<ans<<endl;
}