Задача взята с сайта codingame.com
Задача.
Задан набор целых чисел (значения температуры за различные моменты времени). Нужно вывести из них ближайшее к нулю.
Входные данные.
Задан набор целых чисел (значения температуры за различные моменты времени). Нужно вывести из них ближайшее к нулю.
Выходные данные.
Вывести нуль, если [latex] N = 0[/latex]. В противном случае вывести число, ближайшее к нулю, причём если два числа разных знаков одинаково близки к нулю, нужно вывести положительное.
Решение.
Сначала отфильтруем случай, когда [latex] N = 0[/latex]. В этом случае, как от нас и требуют, напечатаем нуль.
Если же [latex] N > 0 [/latex], прибегнем к уже знакомому нам приёму. Введём новую переменную — min — и присвоим ей первое число. Затем в цикле for будем эту переменную менять, если наткнёмся число, более близкое к нулю, чем хранящееся в min. Вот основной вопрос: когда нам нужно менять min? «Число [latex] a [/latex] ближе к нулю, чем число [latex] b [/latex]» означает, что [latex] a [/latex] по модулю меньше, чем [latex] b [/latex]. Значит, если число, прочитанное на текущем шаге цикла, по модулю строго меньше, чем число, хранящееся в min, переменную min нужно обновить. Но есть ещё один случай, когда переменную min следует обновить — это тот случай, когда текущее число положительно и столь же близко к нулю, как и число, хранящееся в min. Это действие даёт нам гарантию того, что если два числа разных знаков одинаково близки к нулю, будет выведено положительное.
Код на С++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <string> #include <math.h> using namespace std; int main() { int N; cin >> N; if (N == 0) cout << 0 << endl; else { int min, temp; cin >> min; for (int i = 1; i < N; i++) { cin >> temp; if ((abs(temp) < abs(min)) || (temp == abs(min))) min = temp; } cout << min; } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import java.util.*; import java.lang.*; import java.io.*; class Main { public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); int N = in.nextInt(); if (N == 0) System.out.println(0); else { int min = in.nextInt(), temp; for (int i = 1; i < N; i++) { temp = in.nextInt(); if ((Math.abs(temp) < Math.abs(min)) || (temp == Math.abs(min))) min = temp; } System.out.println(min); } } } |
P.S.. Возможно, усложнив оператор ветвления можно сделать алгоритм более эффективным за счёт уменьшения числа сравнений или присваиваний.
— Нужна ссылка откуда взялась задача.
— В условии (abs(temp) < abs(min)) || (temp == abs(min)) второй дизъюнкт лишний. Или требуется указать последнее из нескольких одинаковых по модулю значений? - Уберите, пожалуйста, лишние пустые строки в описании. - Рисунок лучше сделать с обтеканием текстом - Когда черновик будет не нужен, удалите его, пожалуйста.
Замечания учтены.
***
Без второго условия может не выполняться требование «если два числа разных знаков одинаково близки к нулю, нужно вывести положительное». Нам нужно как-то избежать, например, ситуации (-2, 2), когда -2 запомнилось, 2 по модулю не строго меньше и программа возвратит -2, хотя должна 2.
Условие temp == abs(min) я ввёл на тот случай, если min хранит отрицательное значение. Если мы в цикле встречаем положительное, равноудалённое с отрицательным, то, благодаря этому условию, min будет хранить именно его.
Понял. Принято.