Как найти минимальное количество операций

В математике не силён, дана такая задача:
даны x, y.

Как из числа x получить число y, используя только операции (x * 2) и (x — 1), затратив при этом наименьшее число попыток?

Можно реализовать простую логику в лоб, если x меньше то умножаем, если больше, то вычитаем. Но есть кейсы, где такое не пройдет, например x = 5, y = 8.
Здесь минимум операций это 2: x — 1, x * 2, тогда как примитивный алогоритм сделал бы три попытки: x * 2, x -1, x — 1.

2 / 2 / 0

Регистрация: 12.04.2021

Сообщений: 55

1

25.06.2021, 14:21. Показов 15573. Ответов 29


Студворк — интернет-сервис помощи студентам

Задача с курсов сириуса, прошу смотреть на примеры ввода и вывода, спасибо заранее за помощьв решении задачи (никак не могу код написать)

Имеется калькулятор, который выполняет три операции:

прибавить к числу X единицу;
умножить число X на 2;
умножить число X на 3.
Определите, какое наименьшее число операций необходимо для того, чтобы получить из числа 1 заданное число N.

Входные данные

Программа получает на вход одно число, не превосходящее 106.

Выходные данные

Требуется вывести одно число: наименьшее количество искомых операций.

Примеры
Ввод:
32718
Вывод:
17

Ввод:
1
Вывод:
0

Ввод:
5
Вывод:
3



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

25.06.2021, 14:21

29

Вездепух

Эксперт CЭксперт С++

10893 / 5892 / 1611

Регистрация: 18.10.2014

Сообщений: 14,764

25.06.2021, 18:19

2

Цитата
Сообщение от vitek2000
Посмотреть сообщение

Входные данные
Программа получает на вход одно число, не превосходящее 106.

Цитата
Сообщение от vitek2000
Посмотреть сообщение

Примеры
Ввод:
32718

Не понял. Но 32718 больше, чем 106.



0



2 / 2 / 0

Регистрация: 12.04.2021

Сообщений: 55

25.06.2021, 18:25

 [ТС]

3

TheCalligrapher, там 10 в 6, не заметил что перекопировалось



0



Catstail

Модератор

Эксперт функциональных языков программированияЭксперт Python

35555 / 19455 / 4071

Регистрация: 12.02.2012

Сообщений: 32,492

Записей в блоге: 13

26.06.2021, 14:11

4

C++
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
#include <iostream>
using namespace std;
 
void calc(int curr, int count, int target, int & min_op)
{
   if (curr==target)
   {
       if (min_op==-1)
          min_op=count;
       else
          min_op=min(count,min_op);
       return;
   }
   calc(curr+1,count+1,target,min_op);
   if ((curr*2)<target) calc(curr*2,count+1,target,min_op);
   if ((curr*3)<target) calc(curr*3,count+1,target,min_op);
}
 
int main() {
    int n,min_op=-1;
    cin >> n;
    calc(1,0,n,min_op);
    cout << min_op << endl;
    return 0;
}



2



2 / 2 / 0

Регистрация: 12.04.2021

Сообщений: 55

26.06.2021, 14:53

 [ТС]

5

Catstail, спасибо большое за код, проверил в вижуал студио, все работает, а вот почему то сириус не принимает…
не понимаю в чем проблема, спасибо за то, что хоть суть решения видна

Миниатюры

Определить наименьшее число операций для того, чтобы используя заданные операции получить из числа 1 заданное число N
 



0



Модератор

Эксперт функциональных языков программированияЭксперт Python

35555 / 19455 / 4071

Регистрация: 12.02.2012

Сообщений: 32,492

Записей в блоге: 13

26.06.2021, 14:56

6

Возможно, не хватает стекового пространства.



1



2 / 2 / 0

Регистрация: 12.04.2021

Сообщений: 55

26.06.2021, 15:23

 [ТС]

7

Catstail, возможно, только вот не знаю как решить данную проблему, постараюсь поискать…

Добавлено через 23 минуты
Catstail, попытался использовать строку

#pragma comment(linker, «/STACK:66777216»)

но не работает, не хвататет все равно



0



Модератор

Эксперт функциональных языков программированияЭксперт Python

35555 / 19455 / 4071

Регистрация: 12.02.2012

Сообщений: 32,492

Записей в блоге: 13

26.06.2021, 16:34

8

Значит, нужно отсекать лишние рекурсивные вызовы.



1



2 / 2 / 0

Регистрация: 12.04.2021

Сообщений: 55

26.06.2021, 17:02

 [ТС]

9

Catstail, ну да, правда не понимаю какие именно, чтобы код работал, не подскажете??



0



Catstail

Модератор

Эксперт функциональных языков программированияЭксперт Python

35555 / 19455 / 4071

Регистрация: 12.02.2012

Сообщений: 32,492

Записей в блоге: 13

26.06.2021, 17:18

10

vitek2000, Можно зайти с другого конца. Если целевое число n кратно трем, то очевидно, что минимальное число операций будет равно n/3. Если число при делении на три дает остаток 1, оно имеет вид 3k+1 то к-во операций будет k+1. Соответственно для числа вида 3k+2 — к-во операций = k+2. Это порождает следующий простейший код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;
 
int main() {
    int n,k;
    cin >> n;
    k=n%3
    if (k==0)
       cout << n/3 << endl;
    else if (k==1) 
       cout  << n/3+1 << endl;
    else
       cout << n/3+2 << endl;
    return 0;
}



2



2 / 2 / 0

Регистрация: 12.04.2021

Сообщений: 55

26.06.2021, 17:24

 [ТС]

11

Catstail, ну кстати логично, только вот пишет неверный ответ, в самом первом тесте с числом 32718 выводит не 17 а 10906, все таки по другому надо, возможно совместить как-то.



0



Модератор

Эксперт функциональных языков программированияЭксперт Python

35555 / 19455 / 4071

Регистрация: 12.02.2012

Сообщений: 32,492

Записей в блоге: 13

26.06.2021, 17:58

12

vitek2000, да, от жары я лопухнулся. Нужно тянуть до ближайшей степени тройки. 3n получается за n операций. Сейчас подумаю.



1



Вездепух

Эксперт CЭксперт С++

10893 / 5892 / 1611

Регистрация: 18.10.2014

Сообщений: 14,764

26.06.2021, 18:49

13

Цитата
Сообщение от Catstail
Посмотреть сообщение

Можно зайти с другого конца. Если целевое число n кратно трем, то очевидно, что минимальное число операций будет равно n/3. Если число при делении на три дает остаток 1, оно имеет вид 3k+1 то к-во операций будет k+1. Соответственно для числа вида 3k+2 — к-во операций = k+2. Это порождает следующий простейший код:

??? Мы не складываем тройки, а перемножаем.

Навскидку: а не пойдет ли тут просто жадный подход:

— если число делится на 3, то делим на 3.
— если число делится на 2, то делим на 2.
— иначе вычитаем 1.

Никакой поиска, т.е. рекурсии, не нужно.



2



Модератор

Эксперт функциональных языков программированияЭксперт Python

35555 / 19455 / 4071

Регистрация: 12.02.2012

Сообщений: 32,492

Записей в блоге: 13

26.06.2021, 18:55

14

Нет, боюсь, что без рекурсии тут не обойтись. Но она сильно ветвящаяся. Поэтому нужна мемоизация (чтобы не перевычислять одно и то же). Или есть какое-либо математическое решение…

Добавлено через 29 секунд
TheCalligrapher, да, это я сильно ошибся.

Добавлено через 2 минуты
TheCalligrapher, похоже, Ваш алгоритм — это то, что нужно! Я перемудрил.



1



Вездепух

Эксперт CЭксперт С++

10893 / 5892 / 1611

Регистрация: 18.10.2014

Сообщений: 14,764

26.06.2021, 19:03

15

Нет, мое предположение неверно уже для 10.

По моему предположению 10 / 2 = 5 — 1 = 4 / 2 = 2 / 2 = 1
А можно лучше 10 — 1 = 9 / 3 = 3 / 3 = 1

Однако предложенная вами рекурсия без мемоизации если и не переполнит стек, то будет работать очень долго.



1



woldemas

654 / 458 / 212

Регистрация: 06.09.2013

Сообщений: 1,266

26.06.2021, 19:20

16

Лучший ответ Сообщение было отмечено vitek2000 как решение

Решение

А что динамика с простой мемоизацией не прокатывает? 10^6 — не так уж много.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<vector>
#include<iostream>
 
int main()
{
    int x;
    std::cin >> x;
    std::vector<int> mem(x + 1, 0);
    for(int i = 2; i <= x; i++) {
        auto min_ops = mem[i - 1] + 1;
        if(i % 2 == 0) min_ops = std::min(min_ops, mem[i / 2] + 1);
        if(i % 3 == 0) min_ops = std::min(min_ops, mem[i / 3] + 1);
        mem[i] = min_ops;
    }
    std::cout << mem.back() << std::endl;
    return 0;
}



3



Вездепух

Эксперт CЭксперт С++

10893 / 5892 / 1611

Регистрация: 18.10.2014

Сообщений: 14,764

26.06.2021, 20:01

17

Цитата
Сообщение от woldemas
Посмотреть сообщение

А что динамика с простой мемоизацией не прокатывает?

??? А о чем, по-вашему, шла речь выше?



1



654 / 458 / 212

Регистрация: 06.09.2013

Сообщений: 1,266

26.06.2021, 20:05

18

TheCalligrapher, так тут дольше речь вести, чем написать.
Другое дело, что у ТС могут ограничения по памяти стоять.



1



Вездепух

Эксперт CЭксперт С++

10893 / 5892 / 1611

Регистрация: 18.10.2014

Сообщений: 14,764

26.06.2021, 20:10

19

Цитата
Сообщение от woldemas
Посмотреть сообщение

так тут дольше речь вести, чем написать.

«Написать»? Написать — задача автора вопроса, а не отвечающих. Хотя не все и не всегда это понимают…



1



2 / 2 / 0

Регистрация: 12.04.2021

Сообщений: 55

26.06.2021, 21:16

 [ТС]

20

woldemas, спасибо большое вам за решение, и всем отвечающим за дискуссию. И в правду мемоизацию надо использовать, динамическое программирование как никак. Всем удачи и еще раз спасибо!!



1



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

26.06.2021, 21:16

Помогаю со студенческими работами здесь

Определите, какое наименьшее число операций необходимо, чтобы получить из числа 1 число N
Имеется калькулятор, который выполняет три операции:
1. Прибавить к числу X единицу.
2. Умножить…

Из числа N, используя наименьшее количество операций, получить число 1000
Есть число N и два действия:

умножить на 2
вычесть 1

Надо из числа N, используя…

Заданы 6 цифр и число. Используя скобки и бинарные арифметические операции +,-,*,/, получить заданное число
помогите написать программу на C#, как-нибудь отблагодарю

Заданы 6 цифр и число. Используя…

Нужно определить, сколько существует способов получить n число из x числа используя заданные математические действия
здравствуйте, здравствуйте, столкнулся с проблемкой. Нужно определить, сколько существует способов…

Определить минимальное количество операций необходимо для того, чтобы сделать число a равным числу b
Помогите пож-ста срочно

Определить, на какое наименьшее число нужно умножить x, чтобы получить квадрат целого числа
Вариант №16
Ввести натуральное число x. Определить, на какое наименьшее целое число нужно умножить…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

20

Let me start with an example —
I have a range of numbers from 1 to 9. And let’s say the target number that I want is 29.
In this case the minimum number of operations that are required would be (9*3)+2 = 2 operations. Similarly for 18 the minimum number of operations is 1 (9*2=18).
I can use any of the 4 arithmetic operators — +, -, / and *.

How can I programmatically find out the minimum number of operations required?
Thanks in advance for any help provided.

clarification: integers only, no decimals allowed mid-calculation. i.e. the following is not valid (from comments below): ((9/2) + 1) * 4 == 22
I must admit I didn’t think about this thoroughly, but for my purpose it doesn’t matter if decimal numbers appear mid-calculation. ((9/2) + 1) * 4 == 22 is valid. Sorry for the confusion.

asked Jan 16, 2012 at 20:14

Bookamp's user avatar

BookampBookamp

6628 silver badges19 bronze badges

12

For the special case where set Y = [1..9] and n > 0:

  • n <= 9 : 0 operations
  • n <=18 : 1 operation (+)
  • otherwise : Remove any divisor found in Y. If this is not enough, do a recursion on the remainder for all offsets -9 .. +9. Offset 0 can be skipped as it has already been tried.

Notice how division is not needed in this case. For other Y this does not hold.

This algorithm is exponential in log(n). The exact analysis is a job for somebody with more knowledge about algebra than I.

For more speed, add pruning to eliminate some of the search for larger numbers.

Sample code:

def findop(n, maxlen=9999):
    # Return a short postfix list of numbers and operations

    # Simple solution to small numbers
    if n<=9: return [n]
    if n<=18: return [9,n-9,'+']

    # Find direct multiply
    x = divlist(n)
    if len(x) > 1:
        mults = len(x)-1
        x[-1:] = findop(x[-1], maxlen-2*mults)
        x.extend(['*'] * mults)
        return x

    shortest = 0

    for o in range(1,10) + range(-1,-10,-1):
        x = divlist(n-o)
        if len(x) == 1: continue
        mults = len(x)-1

        # We spent len(divlist) + mults + 2 fields for offset. 
        # The last number is expanded by the recursion, so it doesn't count. 
        recursion_maxlen = maxlen - len(x) - mults - 2 + 1

        if recursion_maxlen < 1: continue
        x[-1:] = findop(x[-1], recursion_maxlen)
        x.extend(['*'] * mults)
        if o > 0:
            x.extend([o, '+'])
        else:
            x.extend([-o, '-'])
        if shortest == 0 or len(x) < shortest:
            shortest = len(x)
            maxlen = shortest - 1
            solution = x[:]

    if shortest == 0:
        # Fake solution, it will be discarded
        return '#' * (maxlen+1)
    return solution

def divlist(n):
    l = []
    for d in range(9,1,-1):
        while n%d == 0:
            l.append(d)
            n = n/d
    if n>1: l.append(n)
    return l

answered Feb 15, 2012 at 11:30

Peer Sommerlund's user avatar

The basic idea is to test all possibilities with k operations, for k starting from 0. Imagine you create a tree of height k that branches for every possible new operation with operand (4*9 branches per level). You need to traverse and evaluate the leaves of the tree for each k before moving to the next k.

I didn’t test this pseudo-code:

for every k from 0 to infinity
  for every n from 1 to 9
    if compute(n,0,k):
      return k


boolean compute(n,j,k):
  if (j == k):
    return (n == target)
  else:
    for each operator in {+,-,*,/}:
       for every i from 1 to 9:
         if compute((n operator i),j+1,k):
           return true
    return false

It doesn’t take into account arithmetic operators precedence and braces, that would require some rework.

answered Jan 16, 2012 at 21:38

cyborg's user avatar

cyborgcyborg

9,9594 gold badges37 silver badges56 bronze badges

1

Really cool question :)

Notice that you can start from the end! From your example (9*3)+2 = 29 is equivalent to saying (29-2)/3=9. That way we can avoid the double loop in cyborg’s answer. This suggests the following algorithm for set Y and result r:

nextleaves = {r}
nops = 0
while(true):
   nops = nops+1
   leaves = nextleaves
   nextleaves = {}
   for leaf in leaves:
      for y in Y:
         if (leaf+y) or (leaf-y) or (leaf*y) or (leaf/y) is in X:
             return(nops)
         else:
             add (leaf+y) and (leaf-y) and (leaf*y) and (leaf/y) to nextleaves

This is the basic idea, performance can be certainly be improved, for instance by avoiding «backtracks», such as r+a-a or r*a*b/a.

answered Jan 19, 2012 at 13:07

mitchus's user avatar

mitchusmitchus

4,6073 gold badges34 silver badges70 bronze badges

I guess my idea is similar to the one of Peer Sommerlund:

For big numbers, you advance fast, by multiplication with big ciphers.

Is Y=29 prime? If not, divide it by the maximum divider of (2 to 9).
Else you could subtract a number, to reach a dividable number. 27 is fine, since it is dividable by 9, so

(29-2)/9=3 => 
3*9+2 = 29 

So maybe — I didn’t think about this to the end: Search the next divisible by 9 number below Y. If you don’t reach a number which is a digit, repeat.

The formula is the steps reversed.

(I’ll try it for some numbers. :) )

I tried with 2551, which is

echo $((((3*9+4)*9+4)*9+4))

But I didn’t test every intermediate result whether it is prime.
But

echo $((8*8*8*5-9)) 

is 2 operations less. Maybe I can investigate this later.

answered Feb 15, 2012 at 11:51

user unknown's user avatar

user unknownuser unknown

35.3k11 gold badges75 silver badges121 bronze badges

Имея две строки, определите, можно ли первую строку преобразовать во вторую строку. Единственная разрешенная операция — перемещение символа из первой строки на передний план. Если строку можно преобразовать, найти минимальное количество операций, необходимых для преобразования.

Например, минимальное количество операций, необходимых для преобразования строки ADCB нанизывать ABCD является 3.

ADCB —> CADB (Move ‘C’ to the front)
CADB —> BCAD (Move ‘B’ to the front)
BCAD —> ABCD (Move ‘A’ to the front)

Потренируйтесь в этой проблеме

1. Чтобы определить, может ли строка быть преобразована в другую строку, проверьте, имеют ли обе строки одинаковый набор символов. Если обе строки имеют разный набор символов, их нельзя преобразовать.

2. Чтобы найти минимальное количество операций, необходимых для преобразования первой строки во вторую, идея состоит в том, чтобы одновременно просмотреть обе строки с конца. Если последние символы обеих строк совпадают, перейдите к следующей паре символов. Если последний символ обеих строк не совпадает, найдите индекс совпадающего символа в первой строке. Разница между обоими индексами представляет собой количество символов в первой строке, которое необходимо переместить перед текущим символом первой строки.

 
Алгоритм может быть реализован следующим образом на C++, Java и Python:

C++

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

69

#include <iostream>

#include <unordered_set>

#include <string>

using namespace std;

// Функция для нахождения минимального количества операций, необходимых для преобразования данного

// строка в другую строку

int getMinimumOperations(string first, string second)

{

    // для отслеживания минимального количества необходимых операций

    int count = 0;

    // `i` и `j` отслеживают текущий индекс символов в

    // первая и вторая строки соответственно

    // начинаем с конца первой и второй строки

    for (int i = first.length() 1, j = i; i >= 0; i, j)

    {

        // если текущий символ обеих строк не совпадает,

        // ищем `second[j]` в подстроке `first[0, i-1]` и

        // увеличиваем счетчик для каждого хода

        while (i >= 0 && first[i] != second[j])

        {

            i;

            count++;

        }

    }

    // вернуть минимальное количество требуемых операций

    return count;

}

// Функция для определения, может ли первая строка быть преобразована в

// вторая строка

bool isTransformable(string first, string second)

{

    // если длина обеих строк отличается

    if (first.length() != second.length()) {

        return false;

    }

    // строим multiset из символов первой и второй строки

    // (используется multiset, так как оно допускает дублирование)

    unordered_multiset<char> chars1(first.begin(), first.end());

    unordered_multiset<char> chars2(second.begin(), second.end());

    // вернуть true, если обе строки имеют одинаковый набор символов

    return (chars1 == chars2);

}

int main()

{

    string first = «ADCB»;

    string second = «ABCD»;

    if (isTransformable(first, second))

    {

        cout << «The minimum operations required to convert the string «

             << first << » to string « << second << » are «

             << getMinimumOperations(first, second);

    }

    else {

        cout << «The string cannot be transformed»;

    }

    return 0;

}

Скачать  Выполнить код

результат:

The minimum operations required to convert the string ADCB to string ABCD are 3

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

69

70

71

72

73

74

75

import java.util.Map;

import java.util.function.Function;

import java.util.stream.Collectors;

class Main

{

    // Функция для нахождения минимального количества операций, необходимых для преобразования данного

    // строка в другую строку

    public static int getMinimumOperations(String first, String second)

    {

        // для отслеживания минимального количества необходимых операций

        int count = 0;

        // `i` и `j` отслеживают текущий индекс символов в

        // первая и вторая строки соответственно

        // начинаем с конца первой и второй строки

        for (int i = first.length() 1, j = i; i >= 0; i, j)

        {

            // если текущий символ обеих строк не совпадает,

            // ищем `second[j]` в подстроке `first[0, i-1]` и

            // увеличиваем счетчик для каждого хода

            while (i >= 0 && first.charAt(i) != second.charAt(j))

            {

                i;

                count++;

            }

        }

        // вернуть минимальное количество требуемых операций

        return count;

    }

    // Функция для определения, может ли первая строка быть преобразована в

    // вторая строка

    public static boolean isTransformable(char[] first, char[] second)

    {

        // базовый вариант

        if (first == null || second == null) {

            return false;

        }

        // если длина обеих строк отличается

        if (first.length != second.length) {

            return false;

        }

        // вернуть true, если обе строки имеют одинаковый набор символов

        return getFrequencyMap(first).equals(getFrequencyMap(second));

    }

    // Вспомогательная функция для создания карты частот

    public static Map<Character, Long> getFrequencyMap(char[] chars)

    {

        return new String(chars).chars().mapToObj(ch -> (char) ch)

                .collect(Collectors.groupingBy(Function.identity(),

                    Collectors.counting()));

    }

    public static void main(String[] args)

    {

        String first = «ADCB»;

        String second = «ABCD»;

        if (isTransformable(first.toCharArray(), second.toCharArray()))

        {

            System.out.println(«The minimum operations required to convert the string «

                    + first + » to string « + second + » are «

                    + getMinimumOperations(first, second));

        }

        else {

            System.out.println(«The string cannot be transformed»);

        }

    }

}

Скачать  Выполнить код

результат:

The minimum operations required to convert the string ADCB to string ABCD are 3

Python

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 collections

# Функция для нахождения минимального количества операций, необходимых для преобразования данного

# в другую строку

def getMinimumOperations(first, second):

    # для отслеживания минимального количества необходимых операций

    count = 0

    # `i` и `j` отслеживают индекс текущего символа в

    # первая и вторая строки соответственно

    # начинаются с конца первой и второй строки

    i = len(first) 1

    j = i

    while i >= 0:

        #, если текущий символ обеих строк не совпадает,

        # ищет `second[j]` в подстроке `first[0,i-1]` и

        # увеличивает счет для каждого хода

        while i >= 0 and first[i] != second[j]:

            i = i 1

            count = count + 1

        i = i 1

        j = j 1

    # возвращает минимально необходимые операции

    return count

# Функция для определения возможности преобразования первой строки в

# вторая строка

def isTransformable(first, second):

    #, если длина обеих строк отличается

    if len(first) != len(second):

        return False

    # возвращает true, если обе строки имеют одинаковый набор символов.

    return collections.Counter(first) == collections.Counter(second)

if __name__ == ‘__main__’:

    first = ‘ADCB’

    second = ‘ABCD’

    if isTransformable(list(first), list(second)):

        print(‘The minimum operations required to convert the String’, first,

              ‘to string’, second, ‘are’, getMinimumOperations(first, second))

    else:

        print(‘The string cannot be transformed’)

Скачать  Выполнить код

результат:

The minimum operations required to convert the string ADCB to string ABCD are 3

Временная сложность приведенного выше решения равна O(n) и требует O(n) дополнительное пространство, где n длина входной строки.

Спасибо за чтение.

Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.

Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования :)

Добрый день,

Хочется понять как высчитать минимальное и максимальное количество операций для нахождения произвольного числа в определенном промежутке значений.
Код для примера (C#):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Random r = new Random();
            int min = 2047;
            int max = 4096;
            int val = min;
            int counter = 0;                
            int i = r.Next(2047, 4096);                
            while(true)
            {
               Console.WriteLine("--> "+val);
               if(i == val) break;                    
               val = (max-min)/2 + min;                    
               if(i>val) {
                   min = val;
               }
               else if(i<val) {
                   max = val;
               }                    
               counter++;
            }                
            Console.WriteLine("nnThe calculated i is: "+val+", but i is: "+i+", done in "+counter+" counts.nnnnn");
        }
    }
}

В данном примере я вижу, что максимальное количество операций для нахождения числа в промежутке между 2047 и 4096 — это 11 (эмпирически, основано на 10000 запусках).
Как это посчетать без запуска? Где можно почитать теоритическое обьяснение?

Спасибо!

задан 8 мар 2017 в 15:39

Michael Vaysman's user avatar

1

Так как Вы с каждой операцией отсекаете половину возможных чисел, то количество операций будет равно log(n, 2) (логарифм от n по основанию 2), где n — разница между максимом и минимумом

ответ дан 8 мар 2017 в 16:19

Qutrix's user avatar

QutrixQutrix

1,2141 золотой знак8 серебряных знаков16 бронзовых знаков

1

Понравилась статья? Поделить с друзьями:
  • Как найти магнитный момент соленоида
  • Как исправить текст в ворде в режиме редактора
  • Не указали код выполняемой функции в сзв тд как исправить
  • Как исправить номер счета фактуры в сданной декларации по ндс
  • Как найти могилку родственника