pku_oj: 8469 Special locks (C ++)

Problem Description

There is a special binary combination lock button connected by n composition (n <30), the button has a concave / convex two states, by hand button changes its state.

However, a headache is that when two button states when you press a button, it is saying the reverse is also adjacent. Of course, if you press the left or the most right-most button, which will only affect adjacent to a button saying.

The current lock state is known, need to solve the problem is, you need at least according to how many times a button in order to lock into a desired target state.

Two input lines, given by the two other long string of 1s and 0s that represents the current / target lock state, where 0 represents concave, convex represents. Output at least need to press the button of the number of operations, if the change can not be achieved, the output impossible.

 

Sample input

011
000

Sample Output

1 



Analysis:
to solve this problem by enumerating, through analysis of the problem, first of all you can get two conclusions:
1. For a button, in fact, only two states: on / off, press the corresponding button / do not follow that every press the button only once at most
2 each button is pressed the order has no effect on the final results of
the general idea:
our ultimate goal is to have two sets of button sequences correspond to equal, all are equal and therefore equivalent to the corresponding two buttons, we can agree on a sequence, from left to right such as analysis, comparing each character in turn,
if they are equal compare the next, if not equal, there are two ways you can flip the state: First, the current button is pressed, the second is pressed down a button. For the former, while a button on the front flip (removal of a special case, see below),
for the latter, the former does not affect a button. * Special case: When the first button is not at the same time, if you take the first flip way, the button has no effect on the former (not actually exist),
but starting from the second button, if you have taken the first approach, the former a button would be affected, therefore, from the beginning of the second button must be a way to flip button.
* Description: From the above general idea, if you start from the second button, still take the first reversal means, it certainly undermines the consistency front button, if this continues to analyze, to restore the consistency of buttons on the front, not outside almost three ways
. first, press the left button on the front of the other, press the button on the front, the three current button is pressed (at this time the current button has been pressed twice)
for the first approach, the scale of the problem began to recover towards the original scale, can not be the solution for the second approach, the scale of possible recovery towards the original scale and reset button in a state
summary, conclusion: in addition to the first button, all other buttons you want to change it state, its state can only be changed by subsequent button state (corresponding to the convention from left to right analysis)
Briefly: For the first button, the discussion classification: 1. Press the current button 2. Press button next to the other button, only press a button next
code is as follows:
. 1 #include <the iostream>
 2 #include <CString>
 . 3  the using  namespace STD;
 . 4  
. 5  void Flipone ( char & S);     // flip single element 
. 6  int GetMin ( int *);         // minimum number taken 
. 7  
. 8  int CNT [ 2 ] = { 0 };
 . 9  
10  int main ()
 . 11  {
 12 is      char A [ 35 ], B [ 35 ], C [ 35 ];
 13 is      CIN >> >> AB;
 14      int len = strlen (A);
 15      for ( int P = 0 ; P < 2 ; P ++) {         // the two cases are discussed 
16          strcpy (C, A);
 . 17          IF (P == . 1 ) {
 18 is              Flipone (C [ 0 ]);
 . 19              Flipone (C [ . 1 ]);
 20 is              CNT [P] ++ ;
 21 is              IF (strcmp (B, C) == 0 )
 22 is                  GOTO In Flag;
 23 is          }
 24          for (int i = 0; i < len - 1; ++i) {        
25             if (c[i] != b[i]) {
26                 Flipone(c[i]);
27                 Flipone(c[i+1]);
28                 if (i+2 < len) {
29                     Flipone(c[i + 2]);
30                 }
31                 cnt[p]++;
32                 if (strcmp(b, c) == 0)
33                     goto flag;
34             }
35         }
36     }
37 flag:
38     int cnt_min = Getmin(cnt);
39     if (strcmp(b, c) == 0)
40         cout << cnt_min << endl;
41     else
42         cout << "impossible" << endl;
43 }
44 
45 void Flipone(char& s)
46 {
47     if (s == '0')
48         s = '1';
49     else
50         s = '0';
51 }
52 
53 int Getmin(int* cnt)
54 {
55     if (cnt[0] > cnt[1])
56         return cnt[1];
57     else
58         return cnt[0];
59 }
 

* Note: not recommended goto statement

 

Guess you like

Origin www.cnblogs.com/laideng/p/11370261.html