IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Программирование (http://www.imho.ws/forumdisplay.php?f=40)
-   -   Задачки для программистов (http://www.imho.ws/showthread.php?t=57497)

Dimm 03.05.2004 15:37

joker99
Убрать его физически тебе придётся для освобождения места. Для этого тебе и надо 2 указателя. Ты относишся к массиву как кругу, по которому бегают 2 указателя. Т.е. такая ситуация:
Код:

--4768
  H T

абсолютна законна. Следующая попытка положить в очередь элемент поставит Tail
на нулевой индекс (под первой -). Туда и попадёт новый объект.

joker99 03.05.2004 19:55

Да, ситуация совершенно законна, но в моём способе это бы выглядело так
Код:

234768
  H  T

Следующая попытка положить в очередь элемент поставит Tail
на нулевой индекс (под 2). Туда и попадёт новый объект.

Dimm 03.05.2004 20:58

joker99
Во-во и если ты пишешь на С++, то у тебя memory leak.
Иначе тебе придётся удалить объект, как я и сказал:
Код:

delete array[head];
array[head] = null;


Dimm 03.05.2004 21:02

2 All

Для тех кто решил задачу с петлёй у связного списка.
Усложняю задачу.
Теперь, после того как один указатель догнал другой, найдите начало петли.
Напоминаю, что указатель на Head очереди у вас сохранён.

Dimm 03.05.2004 23:13

2 All
Так еще одна задачка "на засыпку" :)

Дано бинарное дерево. Ну, например:
Код:

                5
                /  \
              1    4
              / \    \
            3  7    6

Требуется: распечатать его по уровням
Код:


5
1 4
3 7 6

Хе-хе, всего-то :)

a_ber 04.05.2004 10:42

Цитата:

Сообщение от Programmer
2 All

Для тех кто решил задачу с петлёй у связного списка.
Усложняю задачу.
Теперь, после того как один указатель догнал другой, найдите начало петли.
Напоминаю, что указатель на Head очереди у вас сохранён.

Я же написал в начальном посте, что это требуется сделать (причем за линейное время) и естественно О(1) памяти ...

Dimm 04.05.2004 13:29

a_ber
Цитата:

есть ли в нем петля и если есть то где
Да, извини не заметил :(.
Ладно, раз ты уже спрашивал, даю решение.
1) Ставим один из указателей в начало (head), а второй оставляем указывать на последнюю точку встречи.
2) Пускаем их бежать с одинаковой скоростью.
3) Точка их встречи и будет началом петли.

joker99 04.05.2004 23:30

Цитата:

Сообщение от Programmer
joker99
Во-во и если ты пишешь на С++, то у тебя memory leak.
Иначе тебе придётся удалить объект, как я и сказал:
Код:

delete array[head];
array[head] = null;


В твоём оригинальном ответе небыло delete array[head], а было только array[head] = null,значит подразумевался язык с GC, да и вообще было сказано решение не привязанное к языку, а не решение на c++.

Dimm 05.05.2004 08:20

joker99
Ну да, конечно. А теперь представь такую ситуацию.
Мы в языке с GC.
Юзер позвал 10 раз enqueue() и 5 раз dequeue(), получил объекты, поработал с ними и благополучно отпустил. И больше не зовёт очередь. Но эти 5 объектов не будет собраны GC, поскольку ты продолжаешь ссылаться на них.
А теперь представь, что объекты эти занимают каждый много места.
Вота так они и будут болтаться у тебя в памяти как "га*но в проруби".
И всё из-за строки которую ты упрямо отказываешся вставить в свой код споришь уже несколько постов:
array[head] = null;

joker99 05.05.2004 21:30

Согласимся на том что мой вариант был для очереди int, а твой ( после добавления delete array[head]) для объектов

V@nya 08.05.2004 07:21

Вот вам простенькая задачка: дана матрица N*M, заполненная случайным образом 0 и 1. 0-чёрный, а 1-белый цвета. Посчитать число белых "паятен" на чёрном "фоне". Стоящие рядом по вертикали или горизонтали 1 считать за одно пятно (на искосок не считается). Пример:
011100
101101
110001
Здесь 3 "пятна"

Dimm 08.05.2004 10:31

Цитата:

V@nya:
Вот вам простенькая задачка
Действительно, простенькая.

Код:

int iSpots = 0, iCounter = 0;
for (int i = 0; i < M; i++, iCounter = 0)
{
  for(int j = 0; j < N; j++)
  {
      if ( matrix[i][j] == 1 )
        iCounter++;
      else
      {
        if ( iCounter >= 2 )
          iSpots++;
        iCounter = 0;
      } 
  }
}

iSpots - содержит число пятен.


V@nya 08.05.2004 17:22

Programmer, не верно, ты наверно не правильно понял условие, вот ещё пример:
00100
10001
10101
11110
10101
здесь 4 пятна

Dimm 08.05.2004 19:13

V@nya

Больше 2-х единиц как по вертикали так и по горизонтали?

Или одна единица?

joker99 09.05.2004 01:10

Может так:
Код:

int iSpots = 0
for (int i = 0; i < M; i++)
{
  for(int j = 0; j < N; j++)
  {
      if ( matrix[i][j] == 1 )
      {
          FillSpot(matrix,i,j)
          iSpots++;
      }
}

void FillSpot(int* matrix,int i,int j)
{
  if (i>= M  || j>= N || matix[j*M+i]  == 0)
      return;
  matix[i][j] = 2;
  FillSpot(matrix,i+1,j);
  FillSpot(matrix,i-1,j);
  FillSpot(matrix,i,j-1);
  FillSpot(matrix,i,j+1);
}


V@nya 09.05.2004 10:36

joker99, почти правильно,но если i=0, то FillSpot(matrix,i-1,j); вылетит с ошибкой т.к. будет присваивать m[-1,j] двойку.
Я функцию FillSpot (kill) делал так:
void kill(int i, int j)
{
m[i][j]=0;
if (i>1)
if (m[i-1][j]==1) kill(i-1,j);
if (i<N)
if (m[i+1][j]==1) kill(i+1,j);
if (j>1)
if (m[i][j-1]==1) kill(i,j-1);
if (j<M)
if (m[i][j+1]==1) kill(i,j+1);
}
Массив был глобальной переменной

V@nya 09.05.2004 10:39

Programmer, едениц может быть сколько угодно.

Dimm 10.05.2004 23:24

Вот вам еще легонькая задачка.
дано:
1 1 1 = 6
2 2 2 = 6
3 3 3 = 6
4 4 4 = 6
5 5 5 = 6
6 6 6 = 6
7 7 7 = 6
8 8 8 = 6
9 9 9 = 6

Требуется: используя ЛЮБЫЕ арифмитические знаки, сделайте выражение верным. Например: 2 + 2 + 2 = 6.
Какие угодно знаки и где угодно. Главное, что-бы выражение было правильным.

взято с аудиогейта Там же и решение. Так что не смотрите заранее.

V@nya 11.05.2004 16:01

3*3-3=6

V@nya 11.05.2004 16:03

6*6/6=6
6+6-6=6

V@nya 11.05.2004 16:05

2+2+2=6

Dimm 11.05.2004 16:44

V@nya

А ты не мог написать всё в одном посте?
Или посты накручиваешь? Так это запрещено.

P.S. Ты решил самые простые примеры :winkgrin:

V@nya 11.05.2004 16:59

Programmer, посты я не накручиваю, просто как решу пример, сразу кидаю решение, чтобы быть первым.
sqrt(4)+sqrt(4)+sqrt(4)=6
sqrt(9)*sqrt(9)-sqrt(9)=6
куб.корень(8)+куб.корень(8)+куб.корень(8)=6
5+5/5=6
7-7/7=6

Первый как решать сам не додумался, и глянул ответ. (остальное чесно решал сам).

Dimm 11.05.2004 17:32

Цитата:

V@nya:
посты я не накручиваю, просто как решу пример, сразу кидаю решение, чтобы быть первым
Для этого существует кнопочка/линк "Редактировать"

blood_hound 11.05.2004 20:18

(1+1+1)! = 6

V@nya 12.05.2004 16:40

Вот нашёл универсальное решение:
(x^0+x^0+x^0)!=6
где x^0 - это x в 0 степени, а х - любая цифра

Dimm 12.05.2004 18:11

Цитата:

V@nya:
Вот нашёл универсальное решение
Ха, приколист :). Цифры добавлять нельзя.

Vellion 13.05.2004 12:02

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

Для N = 4
1 1 1 1
2 1 1
1 2 1
1 1 2
2 2
3 1
1 3
И того семь вариантов подняться...

ARTi 13.05.2004 18:32

Если неправильно - поправьте ;)
Всего N ступенек и 3 способа подняться с каждой из них на следующую: 3^n вариантов.
Но при поднятии через одну или две ступеньки мы теряем соответственно 1 или 2 варианта. Так как все способы распределены равномерно, то:
(3^n) - (n/3)*2 - (n/3)*1.
Насчет равномерности я соврал ;), потому что есть еще и конец лестницы, в котором, начиная с какого-то момента, не получится перешагнуть через 1 или 2 ступеньки:
(3^n) - (n/3)*2 - (n/3)*1 - 2 - 1.

Вроде так, или в конце рабочего дня я уже не соображаю ;)

Vellion 13.05.2004 20:06

To ARTi
В твоем варианте если N нацело на 3 не делиться, то вообще получаеться дробное количество вариантов.

Avanturist 14.05.2004 16:35

Vellion
А почему у тебя не присутствует вариант 2 2?
И еще у тебя в условии не было сказано что он может через 3 пойти.
Может я чего не понял, поправь :)

Vellion 15.05.2004 20:45

To Avanturist
Да насчет варианта 2 2 совершенно прав, пропустил я.
1 - на следующую
2 - через одну
3 - через две
Варианта как пойти может 3

Bzzik 15.05.2004 21:50

а для n-ого количества ступенек пусть думает кампутер...
var
a,b,c,n:=integer;
begin
readln(n);
for a:=0 to n do
for b:=0 to n div 2 do
for c:= 0 to n div 3 do
if a + 2*b + 3*c = n then
step:=step+1;
writeln(step);
end.

если не прав, поправьте :)

Vellion 15.05.2004 22:13

To Bzzik
Не так все просто. В твоем случае варианты
2 1 1
1 2 1
1 1 2
Это один вариант. Это когда a = 2, b = 1, c = 0 А должно быть три.

Dimm 16.05.2004 00:45

Vellion

Давай ответ, не томи. :)

joker99 16.05.2004 01:23

а так?

Код:

int NumberOfRoutes = 0;
function void countRoutes(int cur)
{
    if (cur == N)
    {
      NumberOfRoutes++;
      return;
    }
    if(cur+1<=N)
      countRoutes(cur+1);
    if(cur+2<=N)
      countRoutes(cur+2);
    if(cur+3<=N)
      countRoutes(cur+1);
}

Запускать countRoutes(0)

Vellion 16.05.2004 01:28

int a, b, c, k;
k = 0;
for (b = 0; b <= N / 2; b++)
for (c = 0; c <= (N - b*2) / 3; c++)
{
a = N - b*2 - c*3;
k += (a + b + c)! / (a! * b! * c!)
}

Ну самособой это будет работать только для не большик N т.к. int у нас ограничен. А так вместо переменной k результат можно представить в виде массива, и работать уже с масивом.

To joker99
У тебя там вроде опечатка
if(cur+3<=N) countRoutes(cur+1);
помоему должно быть
if(cur+3<=N) countRoutes(cur+3);
Тогда считает.

Vellion 16.05.2004 13:41

А если усложнить условие, допустим может за один шаг пройти не только 1, 2 или 3 ступеньки, а скажем m ступенек, где m какоето целое число (задаеться в программе). Остальное условие такое же, посчитать количество вариантов.

joker99 17.05.2004 00:31

Ну тогда так
Код:

int NumberOfRoutes = 0;
function void countRoutes(int cur)
{
    if (cur == N)
    {
      NumberOfRoutes++;
      return;
    }
    for(step = 1;step<=M;step++)
    {
      if(cur+step<=N)
          countRoutes(cur+step);
    }
}


ARTi 24.05.2004 18:00

Зачем делать это циклами? Я понимаю, можно и рекурсию устроить, да такую, чтоб с переполнением стека, но ведь есть же формулы для решения подобных задач, чтобы не городить потом огород.
Я облажался, т.к. формулы этой не помню. Но это не значит, что ее нет ;), а писать циклами можно и операцию умножения.


Часовой пояс GMT +4, время: 12:18.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.