简体   繁体   中英

SPOJ: GENERAL (Time limit exceeded)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM