CSES - Datatähti 2024 alku - Results
Submission details
Task:Käännöt
Sender:andreibe
Submission time:2023-11-06 17:55:12 +0200
Language:Java
Status:COMPILE ERROR

Compiler report

input/Main.java:13: error: cannot find symbol
    record TestCase(int n, int k, int[] ar) {}
    ^
  symbol:   class record
  location: class Main
input/Main.java:20: error: cannot find symbol
    private static TestCase createTestCase(int k) {
                   ^
  symbol:   class TestCase
  location: class Main
input/Main.java:41: error: cannot find symbol
    static boolean tryStupidAlgorithm(TestCase testCase, boolean logOperations) {
                                      ^
  symbol:   class TestCase
  location: class Main
input/Main.java:197: error: cannot find symbol
    static boolean test(TestCase start) {
                        ^
  symbol:   class TestCase
  location: class Main
input/Main.java:39: error: cannot find symbol
        return new TestCase(n,k,ar);
                   ^
  symbol:   class TestCase
  location: class Main
input/Main.java:98: error: cannot find symbol
            TestCase testCase = createTestCase(4);
            ^
  symbol:   class TestCase
  locatio...

Code

import java.util.*;

public class Main {
    private static boolean isSorted(int[] ar) {
        for (int i = 0; i < ar.length - 1; i++) {
            if (ar[i] < ar[i + 1]) {
                continue;
            }
            return false;
        }
        return true;
    }
    record TestCase(int n, int k, int[] ar) {}
    private static void swap(int y, int x, int[] ar) {
        int temp = ar[y];
        ar[y] = ar[x];
        ar[x] = temp;
    }

    private static TestCase createTestCase(int k) {
        int n = k*60;
        int[] ar = new int[n];
        for (int i = 0; i < ar.length; i++) {
            ar[i] = i+1;
        }
        Random random = new Random();
        for (int i = 0; i < 20; i++) {
            int startIndex = random.nextInt(n-k);
            if (k == 4) {
                swap(startIndex, startIndex+3,ar);
                swap(startIndex+1, startIndex+2,ar);
            }
            if (k == 5) {
                swap(startIndex, startIndex+4, ar);
                swap(startIndex+1, startIndex+3, ar);
            }
        }
        shuffleArray(ar);
        return new TestCase(n,k,ar);
    }
    static boolean tryStupidAlgorithm(TestCase testCase, boolean logOperations) {
        int k = testCase.k;
        int[] ar = testCase.ar;

        while (true) {
            boolean changes = false;
            for (int i = 0; i <= ar.length - k; i++) {
                if (ar[i] > ar[i+1]) {
                    swap(i, i+3, ar);
                    swap(i+1,i+2, ar);
                    if (i + 4 < ar.length) {
                        swap(i+1, i+4, ar);
                        swap(i+2, i+3, ar);

                        swap(i, i+3, ar);
                        swap(i+1, i+2,ar);
                    }
                    if (i != ar.length-4) {
                        changes = true;
                    }
                    if (logOperations) {
                        operations.add(i+1);
                        if (i +4 < ar.length) {
                            operations.add(i+2);
                            operations.add(i+1);
                        }

                    }
                }
            }
            //System.out.println(Arrays.toString(ar));
            if (!changes) break;
        }

        return isSorted(ar);
    }
    static int[] copy;

    static ArrayList<Integer> operations = new ArrayList<>();

    private static void shuffleArray(int[] array) {
        int index;
        Random random = new Random();
        for (int i = array.length - 1; i > 0; i--)
        {
            index = random.nextInt(i + 1);
            if (index != i)
            {
                array[index] ^= array[i];
                array[i] ^= array[index];
                array[index] ^= array[i];
            }
        }
    }

    public static void runTestCases() {
        for (int i = 0; i < 100; i++) {
            TestCase testCase = createTestCase(4);
            int[] original = new int[testCase.ar.length];
            System.arraycopy(testCase.ar, 0, original, 0, original.length);

            operations.clear();
            boolean result = test(testCase);

            StringBuilder builder = new StringBuilder();
            if (result) {
                checkResult(original, operations, testCase.k);
                System.out.println(true);

            } else {
                System.out.println(false);
                builder.append("NO\n");
            }
            //System.out.println(builder);
        }
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(Objects.requireNonNull(Main.class.getResourceAsStream("/input.txt")));
        String[] line = scanner.nextLine().split(" ");
        int n = Integer.parseInt(line[0]);
        int k = Integer.parseInt(line[1]);
        int[] ar = new int[n];
        line = scanner.nextLine().split(" ");
        for (int i = 0; i < ar.length; i++) {
            ar[i] = Integer.parseInt(line[i]);
        }
        boolean result = false;
        if (k == 4 || k == 5) {
            result = test(new TestCase(n, k, ar));
        }
        if (k == 2) {
            //bubble sort
            while (true) {
                boolean changes = false;
                for (int i = 0; i < ar.length -1; i++) {
                    if (ar[i] > ar[i+1]) {
                        int temp = ar[i];
                        operations.add(i+1);
                        ar[i] = ar[i+1];
                        ar[i+1] = temp;
                        changes = true;
                    }
                }
                if (!changes) break;
            }
            result = true;
        }
        if (k == 3) {
            while (true) {
                boolean changes = false;
                for (int i = 0; i < ar.length-2; i++) {
                    if (ar[i] > ar[i+2]) {
                        int temp = ar[i];
                        operations.add(i+1);
                        ar[i] = ar[i+2];
                        ar[i+2] = temp;
                        changes = true;
                    }
                }
                if (!changes) break;
            }
            result = isSorted(ar);
        }



        StringBuilder builder = new StringBuilder();
        if (result) {
            builder.append("YES\n");
            builder.append(operations.size()).append("\n");
            for (Integer operation : operations) {
                builder.append(operation).append(" ");
            }
        } else {
            builder.append("NO\n");
        }
        System.out.println(builder);
    }

    private static void checkResult(int[] original, ArrayList<Integer> operations, int k) {
        for (int operation : operations) {
            operation--;
            if (k == 4) {
                swap(operation, operation+3, original);
                swap(operation+1, operation+2, original);
            }
            if (k == 5) {
                swap(operation, operation+4, original);
                swap(operation+1, operation+3, original);
            }
        }
        if (!isSorted(original)) {
            throw new IllegalArgumentException("Not sorted " + Arrays.toString(original));
        }
    }

    static boolean test(TestCase start) {
        if (start.n > start.k * 8) {
            //System.out.println("WHAT?");
            //sort most of array
            tryStupidAlgorithm(start, true);

            //System.out.println("After stupid: " +Arrays.toString(start.ar));

            int[] ar = start.ar;
            //sort the last k*8 elements separately
            int[] smallerAr = new int[start.k * 8];
            for (int i = 0; i < smallerAr.length; i++) {
                smallerAr[i] = ar[ar.length - smallerAr.length + i];
            }
            ArrayList<Integer> operationsCopy = new ArrayList<>(operations);
            operations.clear();

            boolean b = test(new TestCase(smallerAr.length, start.k, smallerAr));
            if (b) {
                for (int operation : operations) {
                    operationsCopy.add(operation+ (ar.length - smallerAr.length));
                }
            }
            operations = operationsCopy;

            return b;
        }
        //System.out.println("32 array: " + Arrays.toString(start.ar));
        copy = new int[start.ar.length];
        long startTime = System.currentTimeMillis();
        Random random = new Random();
        while ((System.currentTimeMillis() - startTime) < 800) {
            int randomIndex = random.nextInt(start.ar.length+1 - start.k);
            if (start.k == 4) {
                swap(randomIndex, randomIndex+3, start.ar);
                swap(randomIndex+1, randomIndex+2, start.ar);
            }
            if (start.k == 5) {
                swap(randomIndex, randomIndex+4, start.ar);
                swap(randomIndex+1, randomIndex+3, start.ar);
            }
            operations.add(randomIndex+1);

            System.arraycopy(start.ar, 0, copy, 0, start.ar.length);
            boolean res = tryStupidAlgorithm(new TestCase(start.n, start.k, copy), false);
            if (res) {
                System.arraycopy(start.ar, 0, copy, 0, start.ar.length);
                tryStupidAlgorithm(new TestCase(start.n, start.k, copy), true);
                break;
            }
        }
        return isSorted(copy);
        //System.out.println(builder);
        //System.out.println(System.currentTimeMillis() - startTime);
        //System.out.println(operations.size());
    }
}