powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Выборка из миллиарда
25 сообщений из 88, страница 2 из 4
Выборка из миллиарда
    #38639406
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ПЕНСИОНЕРКАmaxtrav,
[src VB]
Sub w140513_0845()
Dim s1, s2, j1, j2
''Выборка из миллиарда
''
''Условие задачи.
''
''Из числового интервала от единицы до миллиарда выбираются случайным образом без
''повторений миллион чисел и записываются в файл.
''Необходимо за приемлемое время выяснить, какое наименьшее число отсутствует в файле.
''Использовать массивы или иные структуры данных, их заменяющие, запрещается.


а по вашему строка из кучи символов это не массив?
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639414
Фотография ПЕНСИОНЕРКА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

нет, это файл на диске, согласно условию задачиавторповторений миллион чисел и записываются в файл.
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639426
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ПЕНСИОНЕРКАkealon(Ruslan),

нет, это файл на диске, согласно условию задачиавторповторений миллион чисел и записываются в файл.

и вы его полностью в строку решили загрузить?
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639585
ALOTE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может я чего не понял, но по-моему все тривиально - объявляется интервал с нижней и верхней границей 1..1000000000. Потом идется по файлу. Если встреченное число рано нижней границе к нижней границе прибавляется 1 , если меньше верхней, верхняя равна встреченному числу. Если нижняя граница становится равна верхней, начинаем заново, но нижней границе+1, а верхнюю опять делаем опять 1000000000.
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639594
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALOTE, а если-бы в задаче надо было найти две нижних "дырки" ?
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639602
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почитал топик, оказывается очень хорошая задачка ... чтобы проверить как разработчики умеют понимать ТЗ :)

...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639623
ALOTE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonALOTE, а если-бы в задаче надо было найти две нижних "дырки" ?
То же самое, нижняя граница+1
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639647
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALOTE, хех. Хвастун. А вот тебе еще мысль. Дана выборка из 2^32 - 1 уникальных элементов int.
Я вот думаю как найти дырку без использования проверок условий "if-then-else".
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639652
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALOTEМожет я чего не понял, но по-моему все тривиально - объявляется интервал с нижней и верхней границей 1..1000000000. Потом идется по файлу. Если встреченное число рано нижней границе к нижней границе прибавляется 1 , если меньше верхней, верхняя равна встреченному числу. Если нижняя граница становится равна верхней, начинаем заново, но нижней границе+1, а верхнюю опять делаем опять 1000000000.
и сколько раз придётся читать файл твоему алгоритму в худшем случае ?
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639666
ALOTE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)и сколько раз придётся читать файл твоему алгоритму в худшем случае ?
В худшем случае миллион раз, при условии, что случайная выборка даст отсортированный в обратном порядке массив чисел от 1 до 100000. Но при каждом проходе число читаемых строк будет уменьшаться на 1.
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639669
ALOTE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonALOTE, хех. Хвастун. А вот тебе еще мысль. Дана выборка из 2^32 - 1 уникальных элементов int.
Я вот думаю как найти дырку без использования проверок условий "if-then-else".
Может вообще без программирования?
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639682
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALOTEkealon(Ruslan)и сколько раз придётся читать файл твоему алгоритму в худшем случае ?
В худшем случае миллион раз, при условии, что случайная выборка даст отсортированный в обратном порядке массив чисел от 1 до 100000. Но при каждом проходе число читаемых строк будет уменьшаться на 1.
посмотри мой алгоритм, c бинарным поиском, он делает это гарантированно за 20 проходов и ему неважно в каком порядке данные 10^6 < 2^20

PS: задача то олимпиадная, проверка на входе будет подсовывать самые неудобные случаи
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639693
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonALOTE, хех. Хвастун. А вот тебе еще мысль. Дана выборка из 2^32 - 1 уникальных элементов int.
Я вот думаю как найти дырку без использования проверок условий "if-then-else".
:-)

а сколько чисел в выборке, всего одно выпало?
а While использовать можно?

если всего одно число

сумма всех чисел от 1 до N = (1+N)*N/2
вычитаем из него все числа в файле
итоговым результатом будет невключённое число
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639862
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может XOR-ем попробовать?
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38639894
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поделим миллиардный интервал на два интервала по 500 миллионов. Где может находиться искомое число? Очевидно, в первом, так как 500-миллионный интервал миллионом чисел не заполнить. Теперь поделим первый 500-миллионный интервал на два и т. д. Рано или поздно заключение о том, что интервал, содержащий искомое число, будет первым, окажется несправедливым. Поэтому давайте для любой пары интервалов разработаем более универсальный метод.

Почему очевидно в первом ?
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640044
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПоделим миллиардный интервал на два интервала по 500 миллионов. Где может находиться искомое число? Очевидно, в первом, так как 500-миллионный интервал миллионом чисел не заполнить. Теперь поделим первый 500-миллионный интервал на два и т. д. Рано или поздно заключение о том, что интервал, содержащий искомое число, будет первым, окажется несправедливым. Поэтому давайте для любой пары интервалов разработаем более универсальный метод.

Почему очевидно в первом ?

как уже говорил... автор предоставил избыточное решение (делается больше чем надо). Очевидно, что пропуск находится в одной из первых 1000001 позиций. А значит и 1000 000 000 проверять не надо... достаточно начинать делить интервалы начиная с миллиона (точнее начиная с 0xFFFFF = 1048576, тогда все операции легко сводятся к битовым, а потому идёт экономия времени и упрощение логики).

Код: pascal
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.
Program propusk;
var f: text;
    res: longword;
    mask: longword;
    counter: longword;
    num: longword;
begin
    mask := $80000;
    res := $FFFFF;
    assign(f, 'input.txt');
    while mask>0 do
    begin
        reset(f);
        counter := 0;
        while (not eof(f)) do
        begin
            read(f, num);
            dec(num); {это костыль, все числа сдвигаем на единицу вниз, из-за того, что считаем не от нуля, а от единицы}
            if ((num and res and (not mask))=num) then inc(counter); {если при накладывании маски число не изменилось - оно в нашем интервале}
        end;
        if (counter<mask) then {если счётчик меньше возможного количества чисел в интервале, 
значит нас интересует именно он и потому мы сбрасываем соответствующий бит в 0, иначе мы будем рассматривать интервал "над" данным}
        begin
            res := res and (not mask);
        end;
        mask := mask shr 1;
    end;
    close(f);
    writeln(res+1);
end.



Вот так :) Вот моё решение, на основании решения автора.
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640197
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ох уж эти любители Паскаля...
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640220
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Програмёр]SashaMercuryпропущено...
Вот так :) Вот моё решение, на основании решения автора.

Не работает ваше решение, я его немного модифицировал без потери смысла
Код: pascal
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.
Program propusk;
var
    res: longword;
    mask: longword;
    counter: longword;
    num: longword;
    i:integer;
begin
    mask := $80000;
    res := $FFFFF;

    while mask>0 do
    begin

        counter := 0;
        for i:=1 to 1000001 do
        begin
            if i=11 then continue;
            num:=i;
            dec(num); {это костыль, все числа сдвигаем на единицу вниз, из-за того, что считаем не от нуля, а от единицы}
            if ((num and res and (not mask))=num) then inc(counter); {если при накладывании маски число не изменилось - оно в нашем интервале}
        end;
        if (counter<mask) then {если счётчик меньше возможного количества чисел в интервале,
значит нас интересует именно он и потому мы сбрасываем соответствующий бит в 0, иначе мы будем рассматривать интервал "над" данным}
        begin
            res := res and (not mask);
        end;
        mask := mask shr 1;
    end;

    writeln(res+1);
end. 



выводит 16, хотя должно быть 11
кроме того оно выходит считает файл 32 раза
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640336
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot kealon(Ruslan)]Програмёрпропущено...


Не работает ваше решение, я его немного модифицировал без потери смысла
Код: pascal
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.
Program propusk;
var
    res: longword;
    mask: longword;
    counter: longword;
    num: longword;
    i:integer;
begin
    mask := $80000;
    res := $FFFFF;

    while mask>0 do
    begin

        counter := 0;
        for i:=1 to 1000001 do
        begin
            if i=11 then continue;
            num:=i;
            dec(num); {это костыль, все числа сдвигаем на единицу вниз, из-за того, что считаем не от нуля, а от единицы}
            if ((num and res and (not mask))=num) then inc(counter); {если при накладывании маски число не изменилось - оно в нашем интервале}
        end;
        if (counter<mask) then {если счётчик меньше возможного количества чисел в интервале,
значит нас интересует именно он и потому мы сбрасываем соответствующий бит в 0, иначе мы будем рассматривать интервал "над" данным}
        begin
            res := res and (not mask);
        end;
        mask := mask shr 1;
    end;

    writeln(res+1);
end. 



выводит 16, хотя должно быть 11
кроме того оно выходит считает файл 32 раза


Сильно извиняюсь :) реально ошибся... в последний момент перед заливкой поправил и не проверил. В условии увеличения счётчика ошибся... вот код с правильным накладыванием маски:
Код: pascal
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.
Program propusk;
var
    res: longword;
    mask: longword;
    counter: longword;
    num: longword;
    i:longword;
begin
    mask := $80000;
    res := $FFFFF;

    while mask>0 do
    begin

        counter := 0;
        for i:=1 to 1000001 do
        begin
            if i=11 then continue;
            num:=i;
            dec(num); {это костыль, все числа сдвигаем на единицу вниз, из-за того, что считаем не от нуля, а от единицы}
            if ((num xor (res and (not mask)))<mask) then inc(counter); {если при накладывании маски число не изменилось - оно в нашем интервале}
        end;
        if (counter<mask) then {если счётчик меньше возможного количества чисел в интервале,
значит нас интересует именно он и потому мы сбрасываем соответствующий бит в 0, иначе мы будем рассматривать интервал "над" данным}
        begin
            res := res and (not mask);
        end;
        mask := mask shr 1;
    end;

    writeln(res+1);
end. 



файл читается 20 раз... Ровно столько раз, сколько бит в самом большом числе искомого интервала (в нашем случае это 1000001 < 2^20).
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640452
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ребята, вы издеваетесь ?

Я уже единственное нормальное, и с большой долей вероятности самое быстрое решение привёл вышел.

такая постановка решается очень просто :), код примерно такой:
SS
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//поиск единственного отсутствующего
	int res = 1 ^ *(a + 0);
	for (int i = 2; i < 1000001; i++)
	{
		res = res^(*(a + i - 1)^i);
	}
	res = res ^ 1000001;


если индексы не напутал, но смысл думаю понятен :)

Програмёркак уже говорил... автор предоставил избыточное решение (делается больше чем надо). Очевидно, что пропуск находится в одной из первых 1000001 позиций. А значит и 1000 000 000 проверять не надо... достаточно начинать делить интервалы начиная с миллиона (точнее начиная с 0xFFFFF = 1048576, тогда все операции легко сводятся к битовым, а потому идёт экономия времени и упрощение логики).

автор предоставил порнографическую постановку задачи, и аналогичное решение задачи.

Удивлён что mayton участвовал в этой вашей дискуссии. Хотя, судя по тому как он тонко намекнул остальным на XOR..
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640457
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пИз числового интервала от единицы до миллиарда выбираются случайным образом без повторений миллион чисел и записываются в файл. Необходимо за приемлемое время выяснить, какое наименьшее число отсутствует в файле. Использовать массивы или иные структуры данных, их заменяющие, запрещается.

ну очевидно что в полученном массиве будет 10^6 чисел, и зачем мне смотреть те индексы что даже не существуют ????

И поэтому вашу фразу

ПрограмёрОчевидно, что пропуск находится в одной из первых 1000001 позиций.
я понимаю как -очевидно что искомое число имеет значение в диапазоне 1 - 10^6+1.

Вот как я вижу эту задачу:
1. Дан массив array мощностью 10^6. Каждый элемент массива целое число в диапазоне от 1 до 10^9. Каждый элемент массива уникален. Найти минимальное пропущенное число в array. К этой задаче решение выше не подходит.

Вот, как мне кажется, вы видите эту задачу.
2. Дан массив array мощностью 10^6. Каждый элемент массива целое число в диапазоне от 1 до 10^6. Каждый элемент массива уникален. Найти минимальное пропущенное число в array. К этой задаче решение выше.


Допустим, мы рассматриваем задачу 1.
Програмёркак уже говорил... автор предоставил избыточное решение (делается больше чем надо). Очевидно, что пропуск находится в одной из первых 1000001 позиций

Возможно, вы хотите сказать что значение искомого числа в диапазоне 1 - 10^6+1, но и это неверно.
Допустим все array[i]=0.5^10^9+i. Тогда минимальное пропущенное 0.5^10^9-1

Значит, вы возможно рассматриваете такую постановку:
3. Дан массив array мощностью 10^6. Каждый элемент массива целое число в диапазоне от 1 до 10^9. Каждый элемент массива уникален. Найти минимальное не включенное в array число из диапазона 1 - 10^9.


И тогда, ДЕЙСТВИТЕЛЬНО, наше число находится в диапазоне 1 - 10^6+1.

Вы рассматриваете задачу 3 ?
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640482
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryРебята, вы издеваетесь ?

Я уже единственное нормальное, и с большой долей вероятности самое быстрое решение привёл вышел.

такая постановка решается очень просто :), код примерно такой:
SS
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//поиск единственного отсутствующего
	int res = 1 ^ *(a + 0);
	for (int i = 2; i < 1000001; i++)
	{
		res = res^(*(a + i - 1)^i);
	}
	res = res ^ 1000001;


если индексы не напутал, но смысл думаю понятен :)

Програмёркак уже говорил... автор предоставил избыточное решение (делается больше чем надо). Очевидно, что пропуск находится в одной из первых 1000001 позиций. А значит и 1000 000 000 проверять не надо... достаточно начинать делить интервалы начиная с миллиона (точнее начиная с 0xFFFFF = 1048576, тогда все операции легко сводятся к битовым, а потому идёт экономия времени и упрощение логики).

автор предоставил порнографическую постановку задачи, и аналогичное решение задачи.

Удивлён что mayton участвовал в этой вашей дискуссии. Хотя, судя по тому как он тонко намекнул остальным на XOR..

Да, просто я когба подбирал аналогичную задачу, забыл о более оптимальном поиске одного пропуска. Потому задачу лучше свести к 2 пропускам, и она станет аналогичной изначальной задаче, только без излишеств. То есть, есть 1000000 чисел в диапазоне 1000002. Найти меньшее из пропущеных чисел.
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640513
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда мы имеем поиск неподвижной точки. Не стал разбираться как сделано у автора по ссылке в первой записи топа(ибо его объяснение мне мягко говоря не нравится), но судя по вашим комментариям у вас что-то аналогичное с алгоритмом ниже.
Код в первом приближении
Код: plaintext
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.
	int a[1000000];

	int min = 1, max = 1000000, res;
	while (max > min)
	{
		int l = 0, r = 0;
		int middle = min + (max - min) / 2;
		for (int i = 0; i<1000000;i++)
		{
			if (*(a + i)>=min && *(a + i) <= middle)  //*a in [min;middle]
			{
				l++;
			}
			else if (*(a + i) > middle && *(a + i) <= max)  //*a in (middle;max]
			{
				r++;
			}
		}

		//Если все элементы уже есть, частный случай
		if (l==(middle-min+1) && r==(max-middle)) 
		{
			res = max + 1;
			break;
		}
		//(Все элементы слева есть )? меняем минимальное значение: меняем максимальное значение;
		(l == (middle - min + 1)) ? min = min + (max - min) / 2 + 1 : max = min + (max - min) / 2;

		//проверка на выход
		if (max == min)
		{
			res = min;
			break;
		}
	}
	printf("%i", res);
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640517
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если не ошибаюсь, количество проходов log_2 (1 000 000). То есть не должно превышать 20, тоже встречал это число.

Так как это частный случай, то всё равно эту задачу можно решить за один проход. Только надо подумать как
...
Рейтинг: 0 / 0
Выборка из миллиарда
    #38640544
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryРебята, вы издеваетесь ?

Я уже единственное нормальное, и с большой долей вероятности самое быстрое решение привёл вышел.

такая постановка решается очень просто :), код примерно такой:
SS
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//поиск единственного отсутствующего
	int res = 1 ^ *(a + 0);
	for (int i = 2; i < 1000001; i++)
	{
		res = res^(*(a + i - 1)^i);
	}
	res = res ^ 1000001;


если индексы не напутал, но смысл думаю понятен :)

Програмёркак уже говорил... автор предоставил избыточное решение (делается больше чем надо). Очевидно, что пропуск находится в одной из первых 1000001 позиций. А значит и 1000 000 000 проверять не надо... достаточно начинать делить интервалы начиная с миллиона (точнее начиная с 0xFFFFF = 1048576, тогда все операции легко сводятся к битовым, а потому идёт экономия времени и упрощение логики).

автор предоставил порнографическую постановку задачи, и аналогичное решение задачи.

Удивлён что mayton участвовал в этой вашей дискуссии. Хотя, судя по тому как он тонко намекнул остальным на XOR..
код на коленке можно приводить любой
рабочей проги, которую можно проверить нету
вот например, при чём здесь последняя i (...^i) ?
Код: plaintext
1.
res = res^(*(a + i - 1)^i);
...
Рейтинг: 0 / 0
25 сообщений из 88, страница 2 из 4
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Выборка из миллиарда
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]