LINUX.ORG.RU

Задача «Число операций»

 


0

1

Дано целое неотрицательное число. С ним можно делать следующие операции: увеличивать на 1; уменьшать на 1; делить его на два, если оно четное. Требуется за минимальное число операций получить 0. Вход. Целое неотрицательное число меньше 2000000.

Выход. Минимальное число операций.

http://www.kml.mipt.ru/judge/problems.pl?problem=026

#include <iostream>

using namespace std;

int main() {
    int N, answer = 0;
    cin >> N;
    while(N != 0) {
         if(N%2){
              if( (N+1) % 4){
                   N--;
              }
              else
                  N++;
         }
         else
             N /=2;
         answer++;
    }
    cout << answer << endl;
}

Где ошибка?



Последнее исправление: cetjs2 (всего исправлений: 1)

Ответ на: комментарий от emulek

реккурентное

Это форма представления. Никто не мешает перевести в итерационный вид.

У тебя в твоих PCRE тоже реккурентное

4.2

redgremlin ★★★★★
()
Ответ на: комментарий от mix_mix

Где-то с августа рука тянется тебя заигнорить за тупость.

игнорь. Твои высеры тоже бесполезны лично для меня. Т.ч. я ничего не потеряю, если твоих ответов на свои посты видеть не буду. Как например этот твой пост абсолютно бесполезен для меня лично. Ты его кому писал-то?

emulek
()
Ответ на: комментарий от redgremlin

реккурентное

Это форма представления. Никто не мешает перевести в итерационный вид.

в данном случае — мешает. Не знаю что. Ни у кого не получается.

У тебя в твоих PCRE тоже реккурентное

4.2

обоснуй.

emulek
()
Ответ на: комментарий от MKuznetsov

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

вот на PCRE ты ссылки дал. А почему на это не дал?

показывай свой код дающий корректные ответы

while(n/=2);
emulek
()
Ответ на: комментарий от MKuznetsov

набросал тут аналогичную функцию

int f26_5(int n) { //мой вариант без оглядки на MKuznetsov
	int ans = 0;
	int tmp = 0;
	while (n>3) {
		tmp = n & 3;
		if (tmp == 3) {
			ans += 3;
			n >>= 2;
			n += 1;
		}
		else if (tmp == 2) {
			n >>= 1;
			ans++;
		}
		else if (tmp == 1) {
			ans += 3;
			n >>= 2;
		}
		else {
			ans += 2;
			n >>= 2;
		}
	}
	return ans + n;
}
Побыстрее будет ваших, хотя одно и то же.

parrto
()
Ответ на: комментарий от emulek

Начни удивляться с числа 3

С числа 2 же - --,-- или /,--

anonymous
()
Ответ на: комментарий от emulek

ты упорот.

Возможно, но до Вас мне далече.

Я никакого отношения к «царю» не имею.

Вы такой же в дымину упоротый как и ОН, тока чуток повежливей и с другим лексиконом. Темы Царский сами гуглите.

AIv ★★★★★
()
Ответ на: комментарий от parrto

Побыстрее будет ваших, хотя одно и то же.

ничего не имею против.

Более того, если они дают одинаковые результаты на одинаковых данных (просто ваш вариант я не проверял) то несложными манипуляциями их можно преобразовывать одно в другое, получая по ходу промежуточные варианты.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

точнее я уже запутался с этими замерами. Вроде на мелких числах ваш вариант лучше, а на больших числах лучше мой. +оптимизации компилятора Ваши 3&4

200000000LL Release /03 icc14
1 40187.4 31774.0
3 21285.7 20183.7
4 20737.5 17454.4
5 15772.6 14629
200000000LL Debug /O0 icc14
1 97851.1 96539.8
3 33918.2 33618
4 44974.3 45432.8
5 34333.1 33176.8
6 -       13823.4
20000000LL Release /03 icc14
1 2857.29
3 1702.04
4 1895.81
5 1402.1
20000000LL Debug /O0 icc14
1 9005.97
3 3126.91
4 4047.87
5 3217.64

parrto
()
Ответ на: комментарий от emulek

while(n/=2);

потому-что этот «код» не даёт корректных результатов.

Что, кроме словоблудия решения нет? где там

int emulek_answer(unsigned long N) {
..
}
/**
Вход#1 4 Выход#1 3
Вход#2 15 Выход#2 6
Вход#3 59 Выход#3 9
**/

или принял привычную позу начала отползания ?

MKuznetsov ★★★★★
()
Ответ на: комментарий от parrto

можно компактнее,чуть понятнее и без tmp переписать

int f26_5(int n) { 
	int ans = 0;
	while (n>3) {
		switch( n & 3) {
		case 3 :
			ans += 3;
			n >>= 2;
			n += 1;
		break;
		case 2:
			n >>= 1;
			ans++;
		break;
		case 1:
			ans += 3;
			n >>= 2;
		break;
		default:
			ans += 2;
			n >>= 2;
		}
	}
	return ans + n;
}
очевидно можно и дальше подсокращать - но лень ;-) и можно впасть в грех преждевременной оптимзиции

MKuznetsov ★★★★★
()
Ответ на: комментарий от parrto

А что тут сокращать то?

подумать после какого из case и когда может получиться N<=3 и вынести проверку из общего цикла

MKuznetsov ★★★★★
()
Ответ на: комментарий от emulek

блин... Мы оптимальное ищем, или НЕ оптимальное(в т.ч. и моё) тоже пойдёт?

Ответ всегда правильный. Всегда минимум.

И своё решение можешь улучшить: +1 надо делать тогда, и только тогда, когда n%8==7. В других случаях выигрыша от +1 НЕ будет. Можешь проверить, что там нужно -1 или /=2.

Вот потому и неоптимально (с точки зрения скорости работы программы).

Просто это то решение, которое мне первым пришло в голову

Waterlaz ★★★★★
()
Ответ на: комментарий от parrto

рекурсия подходит по времени и памяти, но моветон же

Ну... это динамическое программирование сверху вниз

Waterlaz ★★★★★
()
Ответ на: комментарий от MKuznetsov

сокращать
запись короче

не про оптимизацию ведь

и хуже

бесспорно.

anonymous
()
Ответ на: комментарий от AIv

Вы такой же в дымину упоротый как и ОН, тока чуток повежливей и с другим лексиконом. Темы Царский сами гуглите.

вот на ваше сознание похоже сильно сказалось общение с этим вашим царём.

Всё же попробуйте спуститесь с небес вашего ЧСВ на землю моего уровня, и задумайтесь о том, что выполнять операции всё равно придётся. Что бы вы там не говорили про «условие» и «acm».

Т.е. для выяснения того, что делать, инкремент, или декремент, придётся таки посчитать остаток от деления. Единственный вариант, как этого «не делать», это метод подбора. Но и в нём вы тоже будете проверять, и тоже выполнять эти операции, дабы найти кратчайший путь.

ЗЫЖ уж я не знаю, что у вас за интим был с царём, но в нашей беседе вы именно упёрлись, и полностью уверены в том, что вы правы, просто потому, что иначе и не может быть. Ваше довление вашим «авторитетом» выглядит довольно смешно в связи с отсутствием других аргументов.

Какая у вас аргументация, кроме «я прав, ибо я умный!» и «оппонент неправ, ибо упорот как царь, только вежливее»? Продолжите в том же духе? Скучно...

emulek
()
Ответ на: комментарий от anonymous

ты что, завидуешь? Что кто-то осилил завязать и бросить пагубную привычку, а ты так и остался тряпкой по жизни?

emulek
()
Ответ на: комментарий от MKuznetsov

вот так пойдёт?

#include <stdio.h>

int main()
{
	int i, n, c;
	for(i = 0; i < 16; i++)
	{
		n = i;
		c = 0;
		const char *z = "";
		printf("%d: ", n);
		while(n != 0)
		{
			if(n%2 == 0)
				n /= 2;
			else
			{
				if(n%8 == 7)
					n++;
				else
					n--;
			}
			printf("%s%d", z, n);
			z = ",";
			c++;
		}
		printf(" |%d\n", c);
	}
	return 0;
}

выхлоп

0:  |0
1: 0 |1
2: 1,0 |2
3: 2,1,0 |3
4: 2,1,0 |3
5: 4,2,1,0 |4
6: 3,2,1,0 |4
7: 8,4,2,1,0 |5
8: 4,2,1,0 |4
9: 8,4,2,1,0 |5
10: 5,4,2,1,0 |5
11: 10,5,4,2,1,0 |6
12: 6,3,2,1,0 |5
13: 12,6,3,2,1,0 |6
14: 7,8,4,2,1,0 |6
15: 16,8,4,2,1,0 |6

emulek
()
Ответ на: комментарий от MKuznetsov

Вход#3 59 Выход#3 9

угу. Ещё надо пофиксить 111011, 111011011, 111011011011, 111011011011011

А вот 111011011011011011 уже не нужно фиксить(ибо 243419).

emulek
()
Ответ на: комментарий от emulek

как-то так

18c18
< 				if(n%8 == 7)
---
> 				if(n%8 == 7 || n%64 == 59)

58: 29,28,14,7,8,4,2,1,0 |9
59: 60,30,15,16,8,4,2,1,0 |9
60: 30,15,16,8,4,2,1,0 |8

emulek
()
Ответ на: =) от Deleted

С чего тебя так торкнуло, что аж двое суток не отпускает?

не скажу. А то мну забанят по 6.13 IRL

emulek
()
Ответ на: комментарий от emulek

Какая у вас аргументация, кроме «я прав, ибо я умный!»

Я выше приводил. Еще раз, для Царей - операции выполнять можно какие угодно, время на их выполнение ничтожно мало. Необходимо НАЙТИ (не ВЫПОЛНИТЬ а НАЙТИ - понимаете разницу?) минимальное число операций --, ++, /2, за которое x превращается в ноль.

Сами найденные операции можете не выполнять, можете выполнять - это неважно, up to you. Но в отрыве от контекста задачи нет никакого смысла их выполнять над x, поскольку ответ и так известен (ноль). Любой код, правильно решающий эту задачу за разумное время (в условии ограничений нет - значит это время субъективное которое не лень ждать, скажем неск. секунд) и использующий хоть спецфункции хоть контурные интегралы имеет право на жизнь, и без всеких причин (время выполнения превышает десятки минут скажем) оптимизировать его глупо.

AIv ★★★★★
()
Последнее исправление: AIv (всего исправлений: 1)
Ответ на: комментарий от AIv

Любой код, правильно решающий эту задачу за разумное время (в условии ограничений нет

В топике нет, по ссылке есть. 5 секунд. Мой код укладывается с большим запасом, он меньше секунды выполняется.

redgremlin ★★★★★
()
Ответ на: комментарий от redgremlin

А если считать как «число ненулевых битов (кроме старшего) + позиция старшего бита»? Я че то не следил за топиком, так делали?;-) Вроде получается...

AIv ★★★★★
()
Ответ на: комментарий от AIv

А не, гоню;-( Это если бы не было декремента (тьфу, ИНКРЕМЕНТА!!!). Сплю еще.

AIv ★★★★★
()
Последнее исправление: AIv (всего исправлений: 1)
Ответ на: комментарий от emulek

вот так пойдёт?

ну хоть что-то ;-) правда это «что-то» не корректно работает (даёт ошибки на 155,182,219...); по крайней мере с такого надо было начинать.

ps. А это вы по жизни так пишите, или приведённый код - результат нервного срыва сделанный на коленке ? :-)

MKuznetsov ★★★★★
()
Ответ на: комментарий от AIv

Я выше приводил. Еще раз, для Царей - операции выполнять можно какие угодно, время на их выполнение ничтожно мало. Необходимо НАЙТИ (не ВЫПОЛНИТЬ а НАЙТИ - понимаете разницу?) минимальное число операций --, ++, /2, за которое x превращается в ноль.

специально для преподавателей, которые придумывают такие дебильные задачи: ваши экзаменуемые НЕ обязаны обладать скилом телепатии. Потому вы ОБЯЗАНЫ прописывать такие вещи в условии. В условии сказано(дословно) :

Требуется за минимальное число операций получить 0

я не наблюдаю тут фразы «только НАЙТИ». Вот в упор не наблюдаю. Если вы думаете, что я(или ваши подопытные) должен прочитать это прямо с ваших извилин — ищите в других местах. На telepaty.org.ru например.

PS: годный детектор завышенного ЧСВ — если поциэнт имеет какую-то точку зрения на какой-нибудь вопрос, то его точка зрения ЕДИНСТВЕННО ВЕРНАЯ, а все остальные — дебилы(цари), и в их слова можно даже не вчитываться. Несогласен? Дебил. Без вариантов.

emulek
()
Ответ на: комментарий от quasimoto

он слишком сильно буферизуется (что в общем-то хорошо), но нельзя в одной консольке запустить программу с редиректом в файл, а в другой смотреть.

Мне больше интересно как это breadth-first обход дерева поиска поканоничней записать.

qnikst ★★★★★
()
Ответ на: комментарий от MKuznetsov

правда это «что-то» не корректно работает (даёт ошибки на 155,182,219...);

ну это надо дальше просчитывать варианты, а мне лениво. Как я уже говорил, профит будет если есть комбинация 111. Но не учёл того, что такой комбинации может и не быть, но она может появится из 1011. Т.е. нужно искать не только n%8==7, но и n%16==11. Может и ещё какие-то варианты возможны. Я не знаю.

ну хоть что-то

дык надо было сразу сказать «ТС переврал условие задачи».

А это вы по жизни так пишите, или приведённый код - результат нервного срыва сделанный на коленке ?

что с кодом-то не так? Ну вообще я его писал можно сказать в полусне.

PS: пофтыкал — код как код. Что не нравится?

emulek
()
Ответ на: комментарий от AIv

«число ненулевых битов (кроме старшего) + позиция старшего бита»

Опровергающий пример:

10101010 => 11
10000111 => 10

redgremlin ★★★★★
()
Ответ на: комментарий от emulek

Т.е. нужно искать не только n%8==7, но и n%16==11. Может и ещё какие-то варианты возможны

вы хотя-бы понимаете, что это будет не решение, а «подгонка под ответ»? Типа студента который подсмотрев ответ подбирает константы в формулу..

что с кодом-то не так? Ну вообще я его писал можно сказать в полусне.

как-бы так сказать..производит впечатление кустарного, содержит детские ошибки. Примерно так пишут неофиты недавно ознакомленные с К&R :) Спишем это на полусонное забытьё

MKuznetsov ★★★★★
()
Ответ на: комментарий от emulek

поразительно. но Вам бы еще

		char *z1="nospacehere";
		..
		printf("%s%d\n", z1, c);
		z1=" |";
добавить, дабы код_стайл.пдф соответствовать, так сказать.

anonymous
()
Ответ на: комментарий от emulek

Я бы Вам посоветовал слушать Крейцерову сонату до просветления. Есть грань между толерантностью (я очень толерантен) и потаканием откровенному бреду. Так вот, Вы несете бред, Вам об этом тыщщу раз уже сказали все присутствующие (не только я), но Вы с упоением продолжаете стоять на своем и еще что то тут бухтите про упертость и упорость собеседников? Идите ка в игнор, нет у меня времени с Вами возиться.

AIv ★★★★★
()
Ответ на: комментарий от MKuznetsov

вы хотя-бы понимаете, что это будет не решение, а «подгонка под ответ»?

а есть другое решение? Оч. интересно с ним ознакомится. Сама задача построена на том, что тройки битов 111 легче и быстрее сводятся к нулю. Т.ч. тут без поиска никак (учитывая, что просто найти тройку битов недостаточно, надо ещё и проверить, появляется-ли она, или нет).

как-бы так сказать..производит впечатление кустарного, содержит детские ошибки.

пример «детских ошибок» можно?

emulek
()
Ответ на: комментарий от AIv

Есть грань между толерантностью (я очень толерантен)

а я — нет.

Так вот, Вы несете бред, Вам об этом тыщщу раз уже сказали все присутствующие (не только я)

я же не виноват, что меня здесь никто не может понять? Ну слишком сложные вещи для вашего понимания, я-то в чём виноват? В том, что я единственный здесь, кто это понимает?

еще что то тут бухтите про упертость и упорость собеседников?

да вы не упёртые и не упорытые — вы даже не пытаетесь ничего понять.

Идите ка в игнор, нет у меня времени с Вами возиться.

Да с удовольствием. Достало слушать ваше нытьё: «тут жеж думать надо, а мне лениво». Ну раз лениво — то и не думайте. И не читайте. А то у вас головка перенапряжётся, и что-нить там сломается.

emulek
()
Ответ на: комментарий от emulek

а есть другое решение? Оч. интересно с ним ознакомится

Ёпрст! пролистай тред вверх - там несколько _разных_ корректных решений.

Т.ч. тут без поиска никак

и как-то все обошлись без поиска и заумствований - чистой логикой

пример «детских ошибок» можно?

посмотри сам. Кстати, в треде присутствуют люди натаскивающие студиозусов - они могут ткнуть, но боюсь тебя уже заигнорили :-)

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Ёпрст! пролистай тред вверх - там несколько _разных_ корректных решений.

я листал. Не нашёл. Ссылку конечно дать не судьба...

и как-то все обошлись без поиска и заумствований - чистой логикой

ага. Снглтонами на питоне. Без них в данной задаче не реально, да. Ну на край — нежадными PCRE.

посмотри сам.

что значит «посмотри сам»? Я вот не вижу. Я вообще не понимаю, что ты там нашёл.

Да, я упоротый, но ты этого не сказал. «Забыл», как и те люди, которые меня заигнорили. Впрочем, почему я не удивлён?

emulek
()

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

Deleted
()
Ответ на: комментарий от emulek

Рассказывай, ничтожество, какой минимум значений функции ceil(sin(x)). А то тут твой эпический фейл потерли.

anonymous
()
Ответ на: комментарий от emulek

Для доказательства существования и единственности решения хватило бы знаний начальных классов школы. Но у тебя, свиньи, даже на это мозгов не хватает.

anonymous
()
Ответ на: комментарий от emulek

я листал. Не нашёл

Задача «Число операций» (комментарий) и далее-далее..все кроме тебя публиковали рабочий код.

что значит «посмотри сам»? Я вот не вижу. Я вообще не понимаю, что ты там нашёл.

потомучто не судьба :-) ты никогда профессионально не писал на С - иначе бы их увидел. Про неспособность понять и решить задачку уже давно ясно. Что ты делаешь в Develop?

Да, я упоротый, но ты этого не сказал.

ты не упорот - а просто тупой и уже скучный троль.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Задача «Число операций» (комментарий) и далее-далее..все кроме тебя публиковали рабочий код.

тащем-то я только ваш код наблюдаю. Проверять его мне лениво. А что там «далее-далее»?

потомучто не судьба :-) ты никогда профессионально не писал на С - иначе бы их увидел. Про неспособность понять и решить задачку уже давно ясно. Что ты делаешь в Develop?

т.е. конкретно сказать вы ничего не можете? Я так и думал.

ты не упорот - а просто тупой и уже скучный троль.

да без проблем. Что тут троллить, если и так мне совершенно ясно, что сама задача с ошибкой в условии? И в таком виде, как Вы её понимаете, она не имеет никакого смысла. Т.е. вообще. Не может иметь. А в бессмысленных задачках — я не очень силён, да.

emulek
()
Ответ на: комментарий от anonymous

А ты, шваль, еще за ceil(sin(x)) не отчитался.

угу. Вот до сих пор ищу ОДНОЗНАЧНЫЙ ЕДИНСТВЕННЫЙ МИНИМУМ. Никак не могу найти. У меня их МНОГО.

ЗЫЖ а ещё я ничего не понимаю в GC. Как ты про это забыл, детка?

emulek
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.