I have been trying to solve this simple problem ( http://br.spoj.com/problems/GENERAL/ ) on spoj for quite some time now, but I keep on getting TLE (Time limit exceeded) for some reason.
Since the problem is in Portuguese, a brief description of the problem is like this (without the story):
You are given an array of size N , you have to arrange the array in ascending order, such that an element can only be swapped with elements which are at a distance k from it. If the array can be sorted then print the number of swaps required to arrange them in ascending order, if it cannot be sorted print impossivel .
This is my code::
#include <iostream>
#include <cstdio>
using namespace std;
int a[100005];
int main() {
int t;
int n, k;
scanf("%d", &t); //number of test cases
while(t--) {
scanf("%d %d", &n, &k);
bool result = true;
int count = 0;
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for(int i = n; i > 0; i = i - k) {
int j = 0;
for( ; j < i - k; j++) {
if(a[j] > a[j + k]) {
int temp = a[j];
a[j] = a[j + k];
a[j + k] = temp;
count++;
}
}
for( ; j < i - 1; j++) {
if(a[j] > a[j + 1]) {
result = false;
break;
}
}
if(!result)
break;
}
if(result)
printf("%d\n", count);
else
printf("impossivel\n");
}
}
My logic : I perform N/k iterations on the array. I initialize the loop variable i to N . In each iteration I check ik elements with the element at a distance k from it, if they are to be swapped then I swap them and increment the number of swaps needed, else I do nothing. Then I check the elements from ik to i , if they are in ascending order, if not I break the loop and print "impossivel", else I change i to ik and again perform the loop. By my logic after every iteration the last k elements will be in ascending order, if is possible to sort them, since at every step I move the elements which are greater to the right.
Does this seem correct to you? How can optimize this further? Thanks for any help in advance. :)
Separate into k sublists of n/k elements each.
Check impossibility condition.
Impossibility condition
Let k = 2 ,
3 4 1 2 is the array
For n/k lists maintain array to see if a number is present in O(1).
For eg. at spaced interval of 2
We can divide into two sublists , 3 1 and 4 2 Now we know sorted is
1 2 3 4 (Use counting sort as heights between 1 and n O(n))
So , we expect 1 at first place. Now ask , can 1 come here? If only it is in sublist.[Y]
If [N] say "impossible"
If impossible we are done else continue.
k times Merge sort, k * n/k(log(n/k))
(The number of inversions is equal to the minimum number of adjacent swaps to sort an array [known property] refer: Sorting a sequence by swapping adjacent elements using minimum swaps )
complexity of approach is n log n , which will easily pass :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.