F
F
fjaerj122021-03-21 14:06:21
C++ / C#
fjaerj12, 2021-03-21 14:06:21

What is wrong with the algorithm for generating the maximum number from the original using binary SS?

Task
The legendary math teacher Yuri Petrovich came up with a fun game with numbers. Namely, taking an arbitrary integer, he translates it into a binary number system, getting some sequence of zeros and ones, starting with one. (For example, the decimal number 1910 = 1*24+0*23+0*22+1*21+1*20 would be written as 10011 in binary.) becomes the first, and all the rest are shifted one position to the right), writing out the resulting sequences of zeros and ones in a column - he noticed that regardless of the choice of the initial number, the resulting sequences begin to repeat from some moment. And, finally, Yuri Petrovich finds the maximum of the numbers written out and translates it back into the decimal number system, considering this number as the result of the performed manipulations. So, for the number 19, the list of sequences will be like this:
10011
11001
11100
01110 00111
10011
...
and
the result of the game, therefore, will be the number 1*24+1*23+1*22+0*21+0*20 = 28

. Most of all, from working with very gifted schoolchildren, you are asked to write a program that would help Yuri Petrovich get the result of the game without tedious manual calculations.

Specifications Input
The input file INPUT.TXT contains one integer N (0 ≤ N ≤ 32767).

Output data
Your program should print to the output file OUTPUT.TXT a single integer equal to the result of the game.

Examples
No. INPUT.TXT OUTPUT.TXT
1 19 28
2 1212 1938

Idea
Find out the number of digits of the number, write them down, duplicate them several times. Then we look for the place where the largest accumulation of units, translate into decimal SS, display.

#include <iostream>
#include <string>
#include <cmath>

int main()
{
    int number = 0, binarCount = 0;
    std::cin >> number;
    std::string binarForm;
    
    int q = 0;
    while (number > 0) 
    {
        binarForm.push_back(number % 2);
        q++;
        number /= 2;
        binarCount++;
    }
    
    for (int i = binarCount - 1; i > -1; i--)
    {
        binarForm.push_back(binarForm[i]);
        q++;
    }
    for (int i = binarCount - 1; i > -1; i--)
    {
        binarForm.push_back(binarForm[i]);
        q++;
    }
    for (int i = binarCount - 1; i > -1; i--)
    {
        binarForm.push_back(binarForm[i]);
        q++;
    }

    int count = 0, number1 = 0, countNumberOne = 0, iteratorNumber = 0;
    for (int i = binarCount; i < 3 * binarCount - 1; i++)
    {
        count++;
        if (binarForm[i] == 1)
        {
            countNumberOne++;
            for (int j = i + 1; j < 3 * binarCount; j++)
            {
                if (binarForm[j] == 1)
                {
                    countNumberOne++;
                }
                if (binarForm[j] == 0)
                {
                    break;
                }
            }

            if (countNumberOne >= number1)
            {
                number1 = countNumberOne;
                iteratorNumber = count - 1;
            }
            countNumberOne = 0;
        }    
    }

    int result = 0, copyBinarCount = binarCount;
    for (int k = copyBinarCount + iteratorNumber; k < 2 * copyBinarCount + iteratorNumber; k++)
    {
        result += pow(2, binarCount - 1) * binarForm[k];
        binarCount--;
    }
    std::cout << result;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
W
Wataru, 2021-03-21
@fjaerj12

Because you can not just look for the maximum accumulation of units. There may be several - which one to choose depends on what comes after them. For example, here is a number in the binary system: 1001110100101110110.
There are 2 pieces of 1110. But the first one is "010", and the second one is "011". Starting with the second one is more profitable.
There are very few restrictions in this problem - you can completely enumerate all possible numbers and take the maximum. You can even not convert to the binary system, but use bitwise operations.
When you know how many bits are in a number, then the least significant bit of x can be obtained as x&1. Shift all bits of a number one position to the right is x >> 1. In this case, the least significant bit disappears. To insert a new bit b on the left you need to dox | (b << k)- here k is the position number of this bit, counting from 0.
Using these operations, you can simply get the next number after the cyclic shift in a loop and search for the maximum from them. Just first find out how many bits are in the number.
And so, for development: If the restrictions were too large (a number of tens of thousands of bits), then smart string algorithms would have to be used here. This would be a problem of finding the lexicographically maximum cyclic shift. Solved using a suffix tree, suffix array, or suffix automaton.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question