Question:Given two strings a and B Consisting of 0 and 1 whose lengths are n (n <= 2000), there are three operations
1: Move a to the Left Loop
2: Shift B to the right
3: change a [I] at the position where B [I] is 1 to (1-A [I]).
Ask the minimum number of operations that change A to B. If a cannot be changed to B,-1 is output.
Input description:Two rows. Each row has n strings that contain only 0 and 1.
Output description:A row with an integer representing the minimum number of operations. If the number cannot be changed from A to B,-1 is output.
Input example:
1010
1100
Output example:
3
Resolution: first judge the case of-1, it is not difficult to find that if B is all 0 and A is all 0, then lose-1. If B is all 0 and A is all 0, then the answer is 0.
Let's take a look at how to calculate the answer. Use L [I] to indicate the number of shifts from position I to left in a before a 1 is available in B. R [I] indicates the number of positions in position I in a shifted to the right, and 1 in position B.
Enumerate the status of final result a (that is, the location to which it is moved), so that the number of modifications is fixed (the number of changes varies between A and B ).
From the previous step, we can conclude that the enumerated state is obtained by moving left (or right) of the original state. Assume that the value is CNT.
Take the left shift as an example. For l [I] of each vertex, if l [I] <= CNT, no additional moving operations will be generated. However, if l [I]> CNT, this point may shift U units from the original position to the right, it is changed when u + L [I] * 2-CNT is moved to the left; it may also be changed when the original position shifts L [I] units to the left and then shifts L [I]-CNT units to the right. Therefore, for each vertex, its value is either the maximum value to the right * 2 + to the left * 2-cnt; or the maximum value to the left * 2-cnt, from which a minimum value can be obtained.
The right operation is similar. See the code for specific implementation details.
The Code is as follows:
1 # include <cstdio> 2 # include <cstring> 3 # include <algorithm> 4 using namespace STD; 5 6 const int maxn = 2005; 7 int n, l [maxn], R [maxn], BJ [maxn], MX, mi, ans; 8 int Tota, totb, Len, que [maxn]; 9 char a [maxn], B [maxn]; 10 11 int CMPL (int A, int B) {12 Return L [a] <L [B]; 13} 14 15 int CMPL (int, int B) {16 return R [a] <R [B]; 17} 18 19 int main () {20 scanf ("% S % s", A + 1, B + 1); n = strlen (a + 1); 21 ans = 2e9; 22 for (INT I = 1; I <= N; ++ I) {// calculate the number of 1 23 if (a [I] = '1') Tota ++; 24 if (B [I] = '1') totb ++; 25} 26 if (! Totb) {// judge-1 27 if (! Tota) return puts ("0"), 0; 28 return puts ("-1"), 0; 29} 30 for (INT I = 1; I <= N; ++ I) {// pre-processing L [I] and R [I] 31 int ind = I, CNT = 0; 32 While (B [ind]! = '1') {33 ind --; CNT ++; 34 if (IND = 0) IND = N; 35} 36 L [I] = CNT; 37 ind = I; CNT = 0; 38 While (B [ind]! = '1') {39 ind ++; CNT ++; 40 if (IND = n + 1) IND = 1; 41} 42 R [I] = CNT; 43} 44 for (INT I = 1; I <= N; ++ I) {// enumerate the final position of the Left endpoint after moving 45 int ind, sum = 0; // sum records the number of points to be modified. 46 if (I = 1) IND = 1; else ind = N-I + 2; 47 for (Int J = 1; j <= N; ++ J) BJ [J] = 0; // BJ [I] indicates whether to modify 48 for (Int J = 1; j <= N; ++ J) {49 if (a [ind]! = B [J]) sum ++, BJ [ind] = 1; 50 ind ++; If (IND> N) IND = 1; 51} 52 int CNT; // CNT indicates the number of digits shifted to the left (or right) 53 if (I = 1) CNT = 0; else CNT = n-I + 1; // CNT indicates the number of digits shifted to the left. 54 Len = 0; 55 for (Int J = 1; j <= N; ++ J) 56 If (BJ [J] & L [J]> CNT) que [++ Len] = J; 57 sort (que + 1, que + 1 + Len, CMIP); 58 MX = 0; MI = 2e9; 59 If (LEN> 0) MI = min (MI, R [que [Len] * 2 + CNT ); 60 for (Int J = Len; j> = 1; -- j) {61 MX = max (MX, L [que [J]); 62 if (j> 1) mi = min (MI, R [que [J-1] * 2 + mx * 2-cnt); 63} 64 if (LEN> 0) MI = min (MI, MX * 2-cnt); 65 if (! Len) MI = CNT; 66 ans = min (ANS, MI + sum); 67 CNT = I-1; Len = 0; // CNT indicates the number of digits shifted to the right 68 for (Int J = 1; j <= N; ++ J) 69 If (BJ [J] & R [J]> CNT) que [++ Len] = J; 70 sort (que + 1, que + 1 + Len, CMPL); 71 MX = 0; MI = 2e9; 72 If (LEN> 0) MI = min (MI, L [que [Len] * 2 + CNT ); 73 for (Int J = Len; j> = 1; -- j) {74 MX = max (MX, R [que [J]); 75 if (j> 1) mi = min (MI, L [que [J-1] * 2 + mx * 2-cnt); 76} 77 If (LEN> 0) MI = min (MI, MX * 2-cnt); 78 If (! Len) MI = CNT; 79 ans = min (ANS, MI + sum); 80} 81 printf ("% d", ANS); 82 return 0; 83}
Agc019d shift and flip (enumeration)