Introduction to the algorithm classic sixth chapter 6-5 mobile Box

Source: Internet
Author: User

Example 6-5 moving box (Boxes in a line, UVa127675)

Question given a row of boxes, numbered from left to right 1,2,...,n. You can execute the following command:

1 X YMove the box X to the left of Y (if it is already on the left, ignore this command)

2 X YMove the box X to the right of Y (if X is already on the right side of Y, ignore this command)

3 X YSwap the positions of X and Y

4Turn the whole order upside down

The instructions are guaranteed to be legal, i.e. x is not equal to Y, the input contains no more than 10 sets of data, the number of first action boxes per group n and the number of instructions m (1<=n,m<=100000).

Output:for each test case, print the sum of numbers at odd-indexed positions. Positions is numbered 1 to Nfrom.

Sample input:

6 41 1 42 3 53 1 646 31 1 42 3 53 1 6100000 14

Sample output:

Case 1: 12Case 2: 9Case 3: 2500050000

如果用数组来求解,复杂度太高,每次要移动大量元素,因此很容易想到用双向链表求解。 当然可以用 自己构造双向链表,或者使用STL的list。
受到前一题的启发,其实可用两个 int 数组来构造双向链表,right 数组表示当前元素的下一个元素的下标,left表示前一个元素的下标。

I 0 1 2 3 4
Left[i] 4 1 2 3 0
Right[i] 1 3 4 2 0
若交换 2和3   1 2 3 4-> 1 3 2 4 (right[i])  

i代表元素位置下标 sum+=1+2=3


I 0 1 2 3 4
Left[i] 4 0 3 1 2
Right[i] 1 3 4 2 0
 

Analysis:

A doubly linked list is used.

1. Using two arrays LEFT[MAXN],RIGHT[MAXN] represents the left or right of the current element, and when this value is 0, it does not exist!

2. For order 4th, reversing the entire sequence, and not really reversing it, but using the Inv record for reversal, using the reversal two times equals no reversal of this truth. The reversal will only affect the 1 command and the 2 command, the 3 command is XY to change it, and will not affect, so on with 1 and 2, direct OP = 3-op can! The use of the Inv variable is also conducive to the final output, the final output found that the inv is 0, is not reversed, then the number of odd positions directly add up can, conversely, the sum minus the even sequence, (because when n is even and reverse the case, sum is actually even position!) )

3. Finally, note that for command number 3rd, xy permutation, XY and XY are separated by many elements, processing is not the same.

If you use an array to solve, the complexity is too high, each time you want to move a large number of elements, so it is easy to think of a doubly linked list solution. Of course, you can construct a doubly linked list by yourself, or use the STL list. Inspired by the previous question, you can actually construct a int doubly linked list of two arrays, which represents the subscript of the rightt next element of the current element, indicating the subscript leftt of the previous element.

#include <iostream>#include <cstdio>using namespacestd;const int MAXN = 100000 + 10; intRightt[maxn],leftt[maxn];////left and righttt is ambiguous void link (int x,intY) {rightt[x]=Y leftt[y]=x;} IntMain () {int n,m,cnt=0; while (scanf ("%d%d", &n,&m) = = 2{for (int i = 0; I <= N; + +)i) {leftt[i]=i-1; rightt[i]= (i+1)% (n+1); } leftt[0]=N Rightt[n]=0; int op,inv=0, X, y; while (m--) {scanf ("%d",&OP); if (op = = 4) INV =!INV; Even-numbered items transpose into odd-numbered 1 2 3 4--4 3 2 1 Else{scanf ("%d%d",&x,&Y); if (op==3&&rightt[y]==x)//In order to convert to the same situation, X, Y is just a code name, anyway the result becomes the valueSwap (x, y); if (Inv && op! = 3) op = 3- op, if (op = = 1 && rightt[x] = = Y) Continue , if (op = = 2 && rightt[y] = = X) continue ; int lx=leftt[x],rx=rightt[x],ry=rightt[y],ly=  Leftt[y]; if (op = = 1 ) {link (lx,rx); link (ly,x); link (x, y);} if (O p = = 2 ) {link (lx,rx); link (y,x); link (x,ry);} When executing command 3, note that if X and Y are adjacent, special handling is required, if (OP = = 3 ) {if (rightt[x]==  Y) {link (lx,y); link (y,x); link (x,ry);} Else
                                
                                  {link (lx,y); link (y,rx); link (ly,x); link (x,ry);}} }}//0 1 2 3 4->1 3 2 4 0 Interchange 2 and 3 results 1+2 long long ans=0 
                                 ; int b = 0 ; for (int i = 1; I <= N; + +  i) {b = rightt[b];//Right-pass if (i% 2 = = 1) ans+=  b;} If n is not an even number, then the result is the same//the last output found that the inv is 0, is not reversed, then directly to the odd position of the numbers add up can, conversely, the sum minus the even sequence, (because when n is even and reverse the case,//sum is actually even position if (n 2 = = 0 && inv) ans = (long Long) (n+1) *n/2- ans; printf ("Case%d:%lld\n", + +  Cnt,ans);} return 0 ;} 
                                

Defining an array with left right is ambiguous

leftright namespace std and is already defined in, which is importing all of the with using namespace std . That's why are you having an ambiguity.

Law II: In the op==3 three kinds of cases of XY adjacent to the two 1 kinds of non-adjacent

#include <iostream>#include <cstdio>using namespacestd;const int MAXN = 100000 + 10; intRightt[maxn],leftt[maxn];void Link (int x,intY) {rightt[x]=Y leftt[y]=x;} IntMain () {int n,m,cnt=0; while (scanf ("%d%d", &n,&m) = = 2{for (int i = 0; I <= N; + +)i) {leftt[i]=i-1; rightt[i]= (i+1)% (n+1); } leftt[0]=N Rightt[n]=0; int op,inv=0, X, y; while (m--) {scanf ("%d",&OP); if (op = = 4) INV =!Inv Else{scanf ("%d%d",&x,&Y); if (Inv && op! = 3) op = 3-Op if (op = = 1 && rightt[x] = = Y) Continue; if (op = = 2 && rightt[y] = = X) Continue; int lx=leftt[x],rx=rightt[x],ry=rightt[y],ly=  leftt[y]; if (op = = 1 ) {link (lx,rx); link (ly,x); Link ( x, y); if (op = = 2 ) {link (lx,rx); link (y,x); link (x,ry);} When executing command 3, note that if X and Y are adjacent, special handling is required, if (OP = = 3 ) {if (rightt[x]==  Y) {link (lx,y); link (y,x); link (x,ry);} else if ( rightt[y]==  X) {link (ly,x); link (x, y); link (y,rx);} else  {link (lx,y); link (y,rx); link (ly,x); link (x,ry);} }}//0 1 2 3 4->1 3 2 4 0 Interchange 2 and 3 results 1+2 long long ans=0 ; int b = 0 ; for (int i = 1; I <= N; + +  i) {b = rightt[b];//Right-pass if (i% 2 = = 1) ans+=  b;} If n is not an even number, then the result is the same//the final output found that the inv is 0, is not reversed, then directly to the odd position of the numbers add up can, conversely, the sum minus the even sequence, (because when n is even and reverse the case,//sum is actually even position/even series Item transpose becomes odd-numbered 1 2 3 4-4 3 2 1 if (n 2 = = 0 && inv) ans = (long Long) (n+1) *n/2- ans; printf ("Case%d:%lld\ N ", + +  Cnt,ans); } return 0 ;}               

Getting started with algorithms classic sixth example 6-5 moving box

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.