Вопрос про abs и решение одной задачи на С++

92
25 ноября 2020, 09:00

Решалась задача: Шахматный король ходит по горизонтали, вертикали и диагонали, но только на 1 клетку. Даны две различные клетки шахматной доски, определите, может ли король попасть с первой клетки на вторую одним ходом.

Решение такое:

#include <iostream>
using namespace std;
int main() {
  int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
if ((abs (x2 - x1) <= 1 && abs (y2 - y1) <= 1)) {
cout << "YES";
}
else {
cout << "NO";
}
  return 0;
}

Сам вопрос: почему именно где модуль <= 1, а не просто ==? Разве мы не сначала делаем число положительным, а потом уже сравниваем?

И на основе этого есть следующая задача: Шахматный конь ходит буквой “Г” — на две клетки по вертикали в любом направлении и на одну клетку по горизонтали, или наоборот. Даны две различные клетки шахматной доски, определите, может ли конь попасть с первой клетки на вторую одним ходом. Решила сделать по аналогу, начертила на листочке и казалось бы поняла логику, но решение неверно:

#include <iostream>
using namespace std;
int main() {
int x1,x2,y1,y2;
    cin>>x1>>x2>>y1>>y2;
    if ((abs(x2-x1)<=2 && abs(y2-y1)<=1) ||(abs(x2-x1)<=1 && abs(y2-y1)<=2))
        cout << "YES";
    else cout << "NO";
    return 0;
}

Спасибо за помощь!

Answer 1
  1. Требуемое условие для короля можно расписать как разрешение на диагональные ходы

    (abs(x2 - x1) == 1 && abs(y2 - y1) == 1) || ...
    

    разрешение на вертикальные ходы

    (abs(x2 - x1) == 1 && abs(y2 - y1) == 0) ||
    (abs(x2 - x1) == 0 && abs(y2 - y1) == 1) || ...
    

    и разрешение остаться на месте

    (abs(x2 - x1) == 0 && abs(y2 - y1) == 0)
    

    Как видите, везде используется строго ==.

    Если условие задач подразумевает, что "остаться на месте" - это тоже допустимый ход, то все эти условия очевидным образом сворачиваются в просто

    (abs(x2 - x1) <= 1 && abs(y2 - y1) <= 1)
    

    Автор кода, очевидно, интерпретировал условие именно так, т.е. "остаться на месте" - это тоже допустимый ход.

    Такая свертка возможна потому, что область допустимых ходов короля - это полностью заполненный "квадратик".

    А вот если запретить вариант "остаться на месте", то эти условия можно свернуть в

    max(abs(x2 - x1), abs(y2 - y1)) == 1
    

    т.е. расстояние в Метрике Чебышева.

  2. В этом случае понадобятся аналогичный набор условий, выраженных именно через ==

    (abs(x2 - x1) == 2 && abs(y2 - y1) == 1) ||
    (abs(x2 - x1) == 1 && abs(y2 - y1) == 2)
    

    Но свернуть их в такой же компактный вариант с <= уже не получится, ибо область допустимых ходов коня не является полностью заполненным прямоугольником.

    И опять же возникает вопрос: а "остаться на месте" - это допустимый ход? Если ответ "да", то вам в ваше условие надо добавить еще условие

    ... || (abs(x2 - x1) == 0 && abd(y2 - y1) == 0) // (x2 == x1 && y2 == y1)
    
READ ALSO
Владение ресурсом через указатель [дубликат]

Владение ресурсом через указатель [дубликат]

Чтобы не заморачиваться с написанием класса-обертки, думаю использовать лямбда + unique_ptr, иначе говоря, пишу

111
Как это работает?

Как это работает?

есть программа:

131
не получается добавить ATL simple object

не получается добавить ATL simple object

Создал ATL Project, в него пытаюсь добавить простой ATL объектНазвал компонент Indexer, вижла создает соответсвующий интерфейс и класс Однако в файле...

144
Аналог frexp (из С++ math.h) в С#

Аналог frexp (из С++ math.h) в С#

Пытаюсь перенести проект с C++ на C#, однако в SystemMath C# отсутствует функция разложения на экспоненту и мантиссу (frexp в C++)

117