Reputation: 29
The body of the problem is as follows: Let n be a positive integer. Let v be an array with n positions counting from 1 to n and its elements being different numbers from 1 to n Consider n being a power of 2(n = 2^m, with m being a positive integer) and array v has the property that for any i from 1 to m and any j from 1 to 2^(m-i), there is a k from 1 to 2^(m-i), so that on the positions in v from 2^i * (j-1)+1 to 2^i * j there are positive integers from 2^i * (k-1)+1 to 2^i * k, randomly. Write a program that sorts the array v in an ascending order, using for changing the order of the elements in v only the operation FLIP(n, v, 2^i * (j-1)+1, 2^i * j), with i from 1 to m and j from 1 to 2^(m-i), using the property of the array v.
The FLIP operation:
void FLIP(int v[], int n, int i, int j) {
while (i < j) {
int aux = v[i];
v[i] = v[j];
v[j] = aux;
i++;
j--;
}
}
Example of input:
n = 16
v = [14 13 15 16 11 12 9 10 2 1 4 3 8 7 6 5]
Output:
v = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
What i found out is that if you group the elements in array v as follows:
2 by 2, the resulting groups have 2 consecutive values(14, 13),(15,16)
4 by 4, the resulting groups have 4 consecutive values(14,13,15,16)
2^i by 2^i, the resulting groups have 2^i consecutive values.
So my mind goes to a divide and conquer approach, but i don't know how to implement it.
Upvotes: 1
Views: 88
Reputation: 841
Think I got it, I think so ... basically a modification of Merge sort, without merging, but instead using the FLIP function that was required to be used. Took me a while, I had an off by one error in there and it took me a minute.
#include <iostream>
using namespace std;
void FLIP(int v[], int n, int i, int j) {
while (i < j) {
int aux = v[i];
v[i] = v[j];
v[j] = aux;
i++;
j--;
}
}
void run(int v[], int n, int l, int r) {
if (n < 2) {
return;
}
if (v[l] > v[r - 1]) FLIP(v, n, l, r-1);
int m = (l + r) / 2;
run(v, n / 2, l, m);
run(v, n / 2, m, r);
}
int main(int argc, char** argv) {
int v[] = { 14,13,15,16,11,12,9,10,2,1,4,3,8,7,6,5 };
run(v, 16, 0, 16);
for (int& x : v) cout << x << ' ';
cout << endl;
}
Upvotes: 2