1

Тема: Алготестер задача №0926.Кухня та котик.Районна олімпіада 2018 задача F

Є розбір цієї задачі і навіть приклад реалізації, але він на С++ і я його не розумію.https://algotester.com/uk/Home/Analysis

https://algotester.com/uk/ArchiveProble … File/40503 - умова задачі.

Програма працює, але алготестер каже, що програма неочікувано завершила роботу.

import java.util.Scanner;

public class Main {
    // код першої букви тобто 'A'
    static int symbol_code = 65;
    static char[][] arr;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt() , m = in.nextInt() , x = in.nextInt() , y = in.nextInt();
        //якщо площа буде парною або сума координат кота буде непарною, то розв'язків немає
        if ( (n % 2) ==0 || (m % 2) == 0 || ((x + y) % 2) == 1 ){
            System.out.println(-1);
            return;
        }

        arr = new char[n][m];
        --x;--y;
        arr[y][x] = '@';
        //заповнюємо плитками горизонтально зліва та справа
        Main.put_horizontal(x,m,n);
        //заповнюємо плитками вертикально зверху та знизу
        Main.put_vertical(y,n,m);
        //перевіряємо чи біля кота є пусті клітник якщо є, то заповнюємо по колу плитками
        Main.check(x,y,n,m);
        //виводимо масив
        for (int i = 0; i < n; i++){
            for(int j =0; j < m; j++){
                System.out.print(arr[i][j] );
            }
            System.out.println("");
        }
    }

    private static void put_horizontal(int x, int m, int n){
        m--;
        int left = 0;
        //поки відстань між крайньою коодинатою і абсцисою кота більша рівна 2, то зверху вниз вкладаємо плитки горизонтально
        while ( m - x >= 2){
            for ( int i =0; i < n; i++){
                arr[i][m] = arr[i][m-1] = (char)symbol_code;
                symbol_code++;
                //якщо код символу рівний 91, то це означає, що великі літери закінчилися, тому
                //ми присвоюємо символ коду значення 97, тобто переходимо на маленьки літери
                if (symbol_code == 91) symbol_code = 97;
            }
            //тепер ми заложили плитки горизонтально і тому крайню праву координату зменшуємо на 2
            m-=2;
        }
        //аналогічно, тільки тепер заповнюємо злівої сторони
        while ( x - left >= 2){
            for ( int i =0; i < n; i++){
                arr[i][left] = arr[i][left+1] = (char)symbol_code;
                symbol_code++;
                //якщо код символу рівний 91, то це означає, що великі літери закінчилися, тому
                //ми присвоюємо символ коду значення 97, тобто переходимо на маленьки літери
                if (symbol_code == 91) symbol_code = 97;
            }
            //тепер ми заложили плитки горизонтально і тому крайню ліву координату збільшуємо на 2
            left+=2;
        }
    }

    private static void put_vertical(int y, int n, int m){
        n--;
        int top = 0;
        // поки відстань між нижньою коднинаю і ординатою кота більша рівна 2 заложуємо плитку вертикально
        while (n - y >= 2) {
            //йдемо зліва направо
            for (int j = 0; j < m; j++){
                if (arr[n][j] == 0 && arr[n-1][j] == 0){
                    arr[n][j] = arr[n-1][j] = (char)symbol_code;
                    symbol_code++;
                    if (symbol_code == 91) symbol_code = 97;
                }
            }
            n-=2;
        }
        //аналогічно тільки тепер зверху на котом
        while (y - top >= 2) {
            for (int j = 0; j < m; j++){
                if (arr[top][j] == 0 && arr[top+1][j] == 0){
                    arr[top][j] = arr[top+1][j] = (char)symbol_code;
                    symbol_code++;
                    if (symbol_code == 91) symbol_code = 97;
                }
            }
            top+=2;
        }
    }

    private static void check(int x, int y, int n, int m){
        boolean empty = false;
        /*якщо координата не виходить за межі масиву, то перевіряємо чи ця клітинка пуста
        і так кожну клітинку
        праворуч, ліворуч, зверху та знизу біля кота*/
        if (x + 1 < m) if ( arr[y][x+1] == 0) empty = true;
        if (x - 1 >= 0) if ( arr[y][x-1] == 0) empty = true;
        if (y + 1 < n) if ( arr[y+1][x] == 0) empty = true;
        if (y - 1 >= 0) if ( arr[y-1][x] == 0) empty = true;
        //якщо є пуста клітинка то це означає, що кругом кота пусто, тому ми по колу застеляємо плитку
        if (empty == true){
            arr[y-1][x-1] =  arr[y-1][x] = (char) symbol_code;
            symbol_code++;
            if (symbol_code == 91) symbol_code = 97;

            arr[y-1][x+1] = arr[y][x+1] = (char) symbol_code;
            symbol_code++;
            if (symbol_code == 91) symbol_code = 97;

            arr[y+1][x+1] = arr[y+1][x] = (char) symbol_code;
            symbol_code++;
            if (symbol_code == 91) symbol_code = 97;

            arr[y+1][x-1] = arr[y][x-1] = (char) symbol_code;
        }
    }
}

Дякую за допомогу і витрачений час!

2

Re: Алготестер задача №0926.Кухня та котик.Районна олімпіада 2018 задача F

А чому у функції m та n передаються у різному порядку? Ви точно нічого не наплутали там?

3

Re: Алготестер задача №0926.Кухня та котик.Районна олімпіада 2018 задача F

Ні, я навмисне так зробив функції

4

Re: Алготестер задача №0926.Кухня та котик.Районна олімпіада 2018 задача F

Ну добре, повірю. Код погано читається, але я бачу, що

arr[i][m]

За умови, що масив має розміри new char[n][m], лежатиме за його межами.

5

Re: Алготестер задача №0926.Кухня та котик.Районна олімпіада 2018 задача F

На початку функцуії m--, тобто m - це крайній правий індекс

zxzpogoncuk написав:
    private static void put_horizontal(int x, int m, int n){
        m--;
        int left = 0;
        //поки відстань між крайньою коодинатою і абсцисою кота більша рівна 2, то зверху вниз вкладаємо плитки горизонтально
        while ( m - x >= 2){
            for ( int i =0; i < n; i++){
                arr[i][m] = arr[i][m-1] = (char)symbol_code;
                symbol_code++;
                //якщо код символу рівний 91, то це означає, що великі літери закінчилися, тому
                //ми присвоюємо символ коду значення 97, тобто переходимо на маленьки літери
                if (symbol_code == 91) symbol_code = 97;
            }
            //тепер ми заложили плитки горизонтально і тому крайню праву координату зменшуємо на 2
            m-=2;
        }
        //аналогічно, тільки тепер заповнюємо злівої сторони
        while ( x - left >= 2){
            for ( int i =0; i < n; i++){
                arr[i][left] = arr[i][left+1] = (char)symbol_code;
                symbol_code++;
                //якщо код символу рівний 91, то це означає, що великі літери закінчилися, тому
                //ми присвоюємо символ коду значення 97, тобто переходимо на маленьки літери
                if (symbol_code == 91) symbol_code = 97;
            }
            //тепер ми заложили плитки горизонтально і тому крайню ліву координату збільшуємо на 2
            left+=2;
        }
    }

  

6

Re: Алготестер задача №0926.Кухня та котик.Районна олімпіада 2018 задача F

Гм. Треба тестувати. Поки що можу порадити написати щось таке

    static char symbol = (char)('A'-1);
    private static char next_symbol()
    {
        if(symbol=='Z')
           symbol = (char)('a'-1);
        if(++symbol>'z')
            throw new System.IndexOutOfRangeException("Літери скінчилися");
        return symbol;
    }

і замість всіх

= (char)symbol_code;
                symbol_code++;
                //якщо код символу рівний 91, то це означає, що великі літери закінчилися, тому
                //ми присвоюємо символ коду значення 97, тобто переходимо на маленьки літери
                if (symbol_code == 91) symbol_code = 97;

писати просто

= next_symbol();

Код стане значно чистішим.

Подякували: zxzpogoncuk1

7 Востаннє редагувалося koala (24.07.2020 21:10:05)

Re: Алготестер задача №0926.Кухня та котик.Районна олімпіада 2018 задача F

Знайшов у вас помилку. "1 5 1 3" що має повертати? А у вас що?

І взагалі переходьте в бік ООП. Щоб код main виглядав десь так:

    Scanner in = new Scanner(System.in);
    int n = in.nextInt(),
        m = in.nextInt(),
        x = in.nextInt(),
        y = in.nextInt();
    Floor floor = new Floor(n,m,x,y);
    if(!floor.is_valid())
    {
        System.out.println(-1);
        return;
    }
    Floor.fill();
    Floor.print();
Подякували: zxzpogoncuk1

8

Re: Алготестер задача №0926.Кухня та котик.Районна олімпіада 2018 задача F

Скористався вашою порадою і дійсно помилку стало набагато простіше знайти. Задача пішла на максимальний бал. Дякую за допомогу.