# 11840 - Moving books
>author: Utin
###### tags: `array`
---
## Brief
See the code below
## Solution 0
```c=
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int N, book[26], shelf[26];
void pile_over(int from, int to);
void pile_onto(int from, int to);
void move_over(int from, int to);
void move_onto(int from, int to);
void print();
void print_value(int a);
void clean(int a);
void connect(int from, int to);
int check(int a, int b);
int main() {
char op[10];
int from, to;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
book[i] = i;
shelf[i] = i;
}
while (1) {
scanf("%s", op);
// exit
if (!strcmp(op, "exit")) break;
// pile
else if (!strcmp(op, "pile")) {
scanf("%d %s %d", &from, op, &to);
if (from == to || check(from, to) || check(to, from)) continue;
else if (!strcmp(op, "onto")) pile_onto(from, to);
else if (!strcmp(op, "over")) pile_over(from, to);
}
// move
else if (!strcmp(op, "move")) {
scanf("%d %s %d", &from, op, &to);
if (from == to || check(from, to) || check(to, from)) continue;
else if (!strcmp(op, "onto")) move_onto(from, to);
else if (!strcmp(op, "over")) move_over(from, to);
}
}
// output
print();
}
void pile_over(int from, int to) {
connect(from, to); //connect from and to
}
void pile_onto(int from, int to) {
clean(to); // clean to
connect(from, to); // connect from and to
}
void move_over(int from, int to) {
clean(from); // clean from
while (to != book[to]) to = book[to]; // search the top book
connect(from, to); // connect from and to
}
void move_onto(int from, int to) {
clean(from); // clean from
clean(to); // clean to
connect(from, to); // connect from and to
}
void print() {
for (int i = 0; i < N; i++) {
printf("%d:", i);
if (shelf[i] != -1) print_value(shelf[i]);
printf("\n");
}
}
void print_value(int a) {
printf(" %d", a);
if (a != book[a]) print_value(book[a]);
}
void clean(int a) {
int curr = a;
while (curr != book[curr]) {
int tmp = curr;
curr = book[curr];
shelf[curr] = curr;
book[tmp] = tmp;
}
}
void connect(int from, int to) {
book[to] = from;
if (shelf[from] == -1) {
for (int i = 0; i < N; i++) {
if (book[i] == from && i != to) {
book[i] = i;
break;
}
}
}
else shelf[from] = -1;
}
int check(int a, int b) {
while (a != book[a]) {
a = book[a];
if (a == b) return 1;
}
return 0;
}
// Utin
```
## Solution 1
```c=
#include <stdio.h>
typedef struct _book {
int num;
struct _book* next, * pre;
} Book;
Book shelf[25], book[25];
void init(int n);
void move_onto(int A, int B);
void move_over(int A, int B);
void pile_onto(int A, int B);
void pile_over(int A, int B);
void clean(int idx);
void connect(int A, int B);
void output(Book* book);
int err(int A, int B);
int main() {
char op[5] = {0};
int N, A, B;
scanf("%d", &N);
init(N);
while (1) {
scanf("%s", op);
if (op[0] == 'e') break;
else if (op[0] == 'm') {
scanf("%d %s %d", &A, op, &B);
if (err(A, B) || err(B, A)) continue;
if (op[1] == 'n') move_onto(A, B);
else move_over(A, B);
}
else {
scanf("%d %s %d", &A, op, &B);
if (err(A, B) || err(B, A)) continue;
if (op[1] == 'n') pile_onto(A, B);
else pile_over(A, B);
}
}
for (int i = 0; i < N; i++) {
printf("%d:", i);
output(shelf[i].next);
printf("\n");
}
}
void init(int n) {
for (int i = 0; i < n; i++) {
shelf[i].next = &book[i];
book[i].num = i;
book[i].next = NULL;
book[i].pre = &shelf[i];
}
}
void move_onto(int A, int B) {
clean(A);
clean(B);
connect(A, B);
}
void move_over(int A, int B) {
clean(A);
Book* curr = &book[B];
while (curr->next) curr = curr->next;
connect(A, curr->num);
}
void pile_onto(int A, int B) {
clean(B);
connect(A, B);
}
void pile_over(int A, int B) {
Book* curr = &book[B];
while (curr->next) curr = curr->next;
connect(A, curr->num);
}
void clean(int idx) {
Book* curr = &book[idx];
while (curr->next) {
curr = curr->next;
curr->pre->next = NULL;
shelf[curr->num].next = curr;
curr->pre = &shelf[curr->num];
}
}
void connect(int A, int B) {
book[B].next = &book[A];
book[A].pre->next = NULL;
book[A].pre = &book[B];
}
void output(Book* book) {
while (book) {
printf(" %d", book->num);
book = book->next;
}
}
int err(int A, int B) {
Book* curr = &book[A];
while (curr) {
if (curr->num == B) return 1;
curr = curr->next;
}
return 0;
}
// Utin
```
## Reference