Orderly Class: Difference between revisions
imported>Kmk21 No edit summary |
imported>Kmk21 No edit summary |
||
Line 25: | Line 25: | ||
[[Category:ICPC Problems]] | [[Category:ICPC Problems]] | ||
[[Category:Mcpc2017]] | [[Category:Mcpc2017]] | ||
[[Category:Scusa2017]] | |||
[[Category:Algorithm Easy]] | [[Category:Algorithm Easy]] | ||
[[Category:Implementation Easy]] | [[Category:Implementation Easy]] | ||
[[Category:Greedy]] | [[Category:Greedy]] | ||
[[Category:Strings]] | [[Category:Strings]] |
Latest revision as of 20:38, 29 December 2017
This problem gives us a pair of strings and asks how many possible ways can we make a single substring reversal to get from the first to the second string.
Given the input length of 100k, the solution must be linear-ish.
Intuitively, we can say the following
- If a prefix or postfix of the two strings matches, it doesn't have to be swapped
- if a character doesn't match between the two strings, it MUST be swapped
So we can use this to find the smallest subset we must swap in order to make the strings match. This substring starts at the first non-matching character, and goes to the last non-matching character. We can prove that either this is a match or there is no match at all as follows
- assume this string does not yield a match when flipped, but some larger substring does
- we know that "right-pre" must match "left-post" and "left-pre" must match "right-post", so that they match after the flip
- along with the above, the the segment contained between the left and right substrings must equal the post string after reversal
- this contradicts our original assumption that the minimal-mismatched substring does not yield a match
So now that we have a minimal flip required, we know that any final solution must require us to expand one character to either side, and by step 2 in the proof above, those characters must be equal. This is seen clearly in the example in the problem, where the minimal mismatch is (xc), which when flipped creates a match. We see we get one more way to do it since the bounding character on either side is an 'a'.
This leads to the following linear algorithm
- Iterate from the start to find the first mismatch
- iterate from the back to find the last mismatch
- check if flipping this minimal string causes a match
- if so, check each pair of surrounding characters to see if we get a "bonus" match by including it