Задача из сборника задач по программированию Юркина А.Г. 2002 г.
Условие задачи:
В шашечном эндшпиле остались белая дамка и две черных пешки, позиции которых известны. Ход белых. Сможет ли дамка срубить одну или сразу обе пешки?
Входные данные:
—lady-позиция дамки;
—pawn1-позиция первой пешки;
—pawn2-позиция второй пешки;
Тесты:
lady | pawn1 | pawn2 | Выходные данные |
a1 | b2 | f6 | Дамка срубит две пешки |
c3 | a1 | b2 | Дамка срубит ничего |
d4 | b6 | f2 | Дамка срубит одну пешку |
Код на языке С++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <iostream> #include <cmath> #include <algorithm> using namespace std; struct position{ char strk; int stlb; }; int main() { //задаем позиции белой дамки и двух черных пешек position lady,pawn1,pawn2; cin>>lady.strk>>lady.stlb; cin>>pawn1.strk>>pawn1.stlb; cin>>pawn2.strk>>pawn2.stlb; cout<<"Дамка срубит"<<" "; //условие 1: пешки не находятся на границе поля if(pawn1.strk!='a' && pawn2.strk!='a' && pawn1.strk!='h' && pawn2.strk!='h' && pawn1.stlb!=1 && pawn2.stlb!=1 && pawn1.stlb!=8 && pawn2.stlb!=8){ //условие 1.1: обе пешки размещены на диагонали с дамкой if(abs(int(lady.strk)-int(pawn2.strk))==abs(lady.stlb-pawn2.stlb) && abs(int(lady.strk)-int(pawn1.strk))==abs(lady.stlb-pawn1.stlb)){ //условие 1.1.1: позиции пешек на диагонали не являются соседними if(abs(int(pawn2.stlb)-int(pawn1.stlb))!=1 && abs(pawn2.strk-pawn1.strk)!=1){ //условие 1.1.1.1: позиции пешек размещены с одной стороны относительно позиции дамки if(abs(int(pawn1.strk)-int(pawn2.strk))<max(abs(int(lady.strk)-int(pawn1.strk)),abs(int(lady.strk)-int(pawn2.strk))) && abs(pawn1.stlb-pawn2.stlb)<max(abs(lady.stlb-pawn1.stlb),abs(lady.stlb-pawn2.stlb)))cout<<"две пешки"; //условие 1.1.1.2: позиции пешек размещены с разных сторон относительно позиции дамки else cout<<"одну пешку"; } //условие 1.1.2: позиции пешек на диагонали являются соседними else cout<<"ничего"; } //условие 1.2: или 1 пешка или 2 размещены на диагонали с дамкой else if(abs(int(lady.strk)-int(pawn1.strk))==abs(lady.stlb-pawn1.stlb) || abs(int(lady.strk)-int(pawn2.strk))==abs(lady.stlb-pawn2.stlb))cout<<"одну"; //условие 1.3: ни одна из пешек не размещена на диагонали с дамкой else cout<<"ничего"; } //условие 2: пешка1 находится на границе else if((pawn1.strk=='a' || pawn1.strk=='h' || pawn1.stlb==1 || pawn1.stlb==8) && (pawn2.strk!='a' || pawn2.strk!='h' || pawn2.stlb!=1 || pawn2.stlb!=8)){ //условие 2.1: пешка2 находится на диагонали с дамкой if(abs(int(lady.strk)-int(pawn2.strk))==abs(lady.stlb-pawn2.stlb) && abs(int(pawn2.stlb)-int(pawn1.stlb))!=1 && abs(pawn2.strk-pawn1.strk)!=1)cout<<"одну"; else cout<<"ничего"; } //условие 3: пешка2 находится на границе else if((pawn2.strk=='a' || pawn2.strk=='h' || pawn2.stlb==1 || pawn2.stlb==8) && (pawn1.strk!='a' || pawn1.strk!='h' || pawn1.stlb!=1 || pawn1.stlb!=8)){ //условие 3.1: пешка1 находится на диагонали с дамкой if(abs(int(lady.strk)-int(pawn1.strk))==abs(lady.stlb-pawn1.stlb) && abs(int(pawn1.stlb)-int(pawn1.stlb))!=1 && abs(pawn1.strk-pawn1.strk)!=1)cout<<"одну"; else cout<<"ничего"; } //условие 4: обе пешки находятся на границе else cout<<"ничего"; return 0; } |
Код на языке Java (первый вариант):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
import java.util.*; import java.lang.*; import java.io.*; class Position { char strk; int stlb; } class Ideone { public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); in.useDelimiter(""); Position lady = new Position(); Position pawn1 = new Position(); Position pawn2 = new Position(); while (in.hasNext()){ lady.strk=(char)in.next().charAt(0); lady.stlb=in.nextInt(); //запоминаем и игнорируем пробелы в вводе char c1=(char)in.next().charAt(0); pawn1.strk=(char)in.next().charAt(0); pawn1.stlb=in.nextInt(); //запоминаем и игнорируем пробелы в вводе char c2=(char)in.next().charAt(0); pawn2.strk=(char)in.next().charAt(0); pawn2.stlb=in.nextInt(); } String ans = new String("Дамка срубит "); //условие 1: пешки не находятся на границе поля if(pawn1.strk!='a' && pawn2.strk!='a' && pawn1.strk!='h' && pawn2.strk!='h' && pawn1.stlb!=1 && pawn2.stlb!=1 && pawn1.stlb!=8 && pawn2.stlb!=8){ //условие 1.1: обе пешки размещены на диагонали с дамкой if(Math.abs((int)lady.strk-(int)pawn2.strk)==Math.abs(lady.stlb-pawn2.stlb) && Math.abs((int)lady.strk-(int)pawn1.strk)==Math.abs(lady.stlb-pawn1.stlb)){ //условие 1.1.1: позиции пешек на диагонали не являются соседними if(Math.abs((int)pawn2.stlb-(int)pawn1.stlb)!=1 && Math.abs(pawn2.strk-pawn1.strk)!=1){ //условие 1.1.1.1: позиции пешек размещены с одной стороны относительно позиции дамки if(Math.abs((int)pawn1.strk-(int)pawn2.strk)<Math.max(Math.abs((int)lady.strk-(int)pawn1.strk),Math.abs((int)lady.strk-(int)pawn2.strk)) && Math.abs(pawn1.stlb-pawn2.stlb)<Math.max(Math.abs(lady.stlb-pawn1.stlb),Math.abs(lady.stlb-pawn2.stlb)))System.out.println(ans+"две пешки"); //условие 1.1.1.2: позиции пешек размещены с разных сторон относительно позиции дамки else System.out.println(ans+"одну пешку"); } //условие 1.1.2: позиции пешек на диагонали являются соседними else System.out.println(ans+"ничего"); } //условие 1.2: или 1 пешка или 2 размещены на диагонали с дамкой else if(Math.abs((int)lady.strk-(int)pawn1.strk)==Math.abs(lady.stlb-pawn1.stlb) || Math.abs((int)lady.strk-(int)pawn2.strk)==Math.abs(lady.stlb-pawn2.stlb))System.out.println(ans+"одну"); //условие 1.3: ни одна из пешек не размещена на диагонали с дамкой else System.out.println(ans+"ничего"); } //условие 2: пешка1 находится на границе else if((pawn1.strk=='a' || pawn1.strk=='h' || pawn1.stlb==1 || pawn1.stlb==8) && (pawn2.strk!='a' || pawn2.strk!='h' || pawn2.stlb!=1 || pawn2.stlb!=8)){ //условие 2.1: пешка2 находится на диагонали с дамкой if(Math.abs((int)lady.strk-(int)pawn2.strk)==Math.abs(lady.stlb-pawn2.stlb) && Math.abs((int)pawn2.stlb-(int)pawn1.stlb)!=1 && Math.abs(pawn2.strk-pawn1.strk)!=1)System.out.println(ans+"одну"); else System.out.println(ans+"ничего"); } //условие 3: пешка2 находится на границе else if((pawn2.strk=='a' || pawn2.strk=='h' || pawn2.stlb==1 || pawn2.stlb==8) && (pawn1.strk!='a' || pawn1.strk!='h' || pawn1.stlb!=1 || pawn1.stlb!=8)){ //условие 3.1: пешка1 находится на диагонали с дамкой if(Math.abs((int)lady.strk-(int)pawn1.strk)==Math.abs(lady.stlb-pawn1.stlb) && Math.abs((int)pawn1.stlb-(int)pawn1.stlb)!=1 && Math.abs(pawn1.strk-pawn1.strk)!=1)System.out.println(ans+"одну"); else System.out.println(ans+"ничего"); } //условие 4: обе пешки находятся на границе else System.out.println(ans+"ничего"); } } |
Код на языке Java (второй вариант):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import java.util.*; import java.lang.*; import java.io.*; class Position { char strk; int stlb; } class Ideone { public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); in.useDelimiter(""); Position lady = new Position(); Position pawn1 = new Position(); Position pawn2 = new Position(); while (in.hasNext()){ lady.strk=(char)in.next().charAt(0); lady.stlb=in.nextInt(); //запоминаем и игнорируем пробелы в вводе char c1=(char)in.next().charAt(0); pawn1.strk=(char)in.next().charAt(0); pawn1.stlb=in.nextInt(); //запоминаем и игнорируем пробелы в вводе char c2=(char)in.next().charAt(0); pawn2.strk=(char)in.next().charAt(0); pawn2.stlb=in.nextInt(); } String ans = new String("Дамка срубит "); if((pawn1.strk!='a' && pawn2.strk!='a' && pawn1.strk!='h' && pawn2.strk!='h' && pawn1.stlb!=1 && pawn2.stlb!=1 && pawn1.stlb!=8 && pawn2.stlb!=8) &&(Math.abs((int)lady.strk-(int)pawn2.strk)==Math.abs(lady.stlb-pawn2.stlb) && Math.abs((int)lady.strk-(int)pawn1.strk)==Math.abs(lady.stlb-pawn1.stlb)) &&(Math.abs((int)pawn2.stlb-(int)pawn1.stlb)!=1 && Math.abs(pawn2.strk-pawn1.strk)!=1) &&(Math.abs((int)pawn1.strk-(int)pawn2.strk)<Math.max(Math.abs((int)lady.strk-(int)pawn1.strk),Math.abs((int)lady.strk-(int)pawn2.strk)) && Math.abs(pawn1.stlb-pawn2.stlb)<Math.max(Math.abs(lady.stlb-pawn1.stlb),Math.abs(lady.stlb-pawn2.stlb))) )System.out.println(ans+"две пешки"); else if((((pawn1.strk!='a' && pawn2.strk!='a' && pawn1.strk!='h' && pawn2.strk!='h' && pawn1.stlb!=1 && pawn2.stlb!=1 && pawn1.stlb!=8 && pawn2.stlb!=8) &&(Math.abs((int)lady.strk-(int)pawn2.strk)==Math.abs(lady.stlb-pawn2.stlb) && Math.abs((int)lady.strk-(int)pawn1.strk)==Math.abs(lady.stlb-pawn1.stlb)) &&(Math.abs((int)pawn2.stlb-(int)pawn1.stlb)!=1 && Math.abs(pawn2.strk-pawn1.strk)!=1) &&(Math.abs((int)pawn1.strk-(int)pawn2.strk)>Math.max(Math.abs((int)lady.strk-(int)pawn1.strk),Math.abs((int)lady.strk-(int)pawn2.strk)) && Math.abs(pawn1.stlb-pawn2.stlb)>Math.max(Math.abs(lady.stlb-pawn1.stlb),Math.abs(lady.stlb-pawn2.stlb)))) ||((pawn1.strk!='a' && pawn2.strk!='a' && pawn1.strk!='h' && pawn2.strk!='h' && pawn1.stlb!=1 && pawn2.stlb!=1 && pawn1.stlb!=8 && pawn2.stlb!=8) &&((Math.abs((int)lady.strk-(int)pawn1.strk)==Math.abs(lady.stlb-pawn1.stlb) && Math.abs((int)lady.strk-(int)pawn2.strk)!=Math.abs(lady.stlb-pawn2.stlb)) || (Math.abs((int)lady.strk-(int)pawn2.strk)==Math.abs(lady.stlb-pawn2.stlb) && Math.abs((int)lady.strk-(int)pawn1.strk)!=Math.abs(lady.stlb-pawn1.stlb))))) ||(((pawn1.strk=='a' || pawn1.strk=='h' || pawn1.stlb==1 || pawn1.stlb==8) && (pawn2.strk!='a' || pawn2.strk!='h' || pawn2.stlb!=1 || pawn2.stlb!=8)) &&(Math.abs((int)lady.strk-(int)pawn2.strk)==Math.abs(lady.stlb-pawn2.stlb) && Math.abs((int)pawn2.stlb-(int)pawn1.stlb)!=1 && Math.abs(pawn2.strk-pawn1.strk)!=1)) ||(((pawn2.strk=='a' || pawn2.strk=='h' || pawn2.stlb==1 || pawn2.stlb==8) && (pawn1.strk!='a' || pawn1.strk!='h' || pawn1.stlb!=1 || pawn1.stlb!=8)) &&(Math.abs((int)lady.strk-(int)pawn1.strk)==Math.abs(lady.stlb-pawn1.stlb) && Math.abs((int)pawn1.stlb-(int)pawn1.stlb)!=1 && Math.abs(pawn1.strk-pawn1.strk)!=1)) )System.out.println(ans+"одну"); else System.out.println(ans+"ничего"); } } |
Решение задачи:
Для описания позиций шашек использовалась структура position с указанием на буквенную строку и числовой столбец шашечной доски. Напомним, что бить можно если дамка и шашка стоят на одной диагонали. Для определения диагонали используется разница между координатами точек (шашек) на заданном шашечном поле. В дальнейшей работе вместо элементов буквенной строки мы используем числовой Unicode код символа, для возможности работать напрямую и со строками, и со столбцами, используя очевидные математически закономерности расположения фигур на поле.
Задача на С++ и ее эквиваленте на Java (в первом варианте) разбивается на 4 главных подзадачи, основанные на таких 4 условиях:
-пешки не находятся на границе шашечного поля;
-первая пешка находится на границе шашечного поля;
-вторая пешка находится на границе шашечного поля;
-обе пешки находятся на границе шашечного поля;
В свою очередь данные подзадачи разбиваются еще на несколько условий, что подробно изложены в комментариях кода. Во втором же варианте задачи кода на Java мы разбиваем задачу на три условия, что в результате нам дает информацию о том побила дамка одну шашку, две или ни одной. Все логические условия рассмотренные в задачах выше сохраняются. На выходе программа предоставляет информацию о том, какое количество пешек срубила дамка относительно заданных позиций.
Условие задачи (стр.31)
Код задачи на C++
Код задачи на Java (первый вариант)
Код задачи на Java (второй вариант)
Молодец, работает! Конечно зачтено!
Но замечания будут.
— Описание, увы, никакое. Можно было бы что-то по сути написать.
Например, указать, что бить можно если дамка и шашка стоят на одной диагонали. А как определяются диагонали? Для одних сумма координат постоянна, а для других — разность. При этом то, что одна из координат буква, никакой роли не играет (буквы кодируются числами и их можно использовать наряду с целыми числами).
Т.е. если мы введем новые координаты в виде суммы и разности старых, то получим прямоугольную систему координат, но развёрнутую на 45 градусов.
Теперь ясно, что бить можно, если одна координата совпадает. ..
— По коду. У Вас три варианта ответа. Значит должно быть два условных оператора. А не 8. Всё сложную логику гораздо лучше «запихнуть» в условия. Тогда точно не будет множества одинаковых операторов. Сейчас Вы в четырех местах выводите про «одну пешку».
Лучше бы всё это поправить…
Добрый вечер, Игорь Евгеньевич. Прислушавшись к Вашим замечаниям, я опубликовала две задачи на Java. Одна абсолютна идентична засчитанной задаче на С++, а второй ее вариант уже с изменениями.