чувак клянётся, что это реальная задачка с нашего интервью. итак:
большая вечеринка. party по-нашему. кто-то кого-то знает, кто-то кого-то нет. отношение "знает" не обязательно симметрично - А может знать Б, а Б - не знать А. особенно "несимметричны" знаменитости. знаменитость определяется как чувак, которого все знают, но который не знает никого. жосткое такое определение, но нужно для удобства задания задачки. то есть если чувак хоть кого-то знает, то он уже не знаменитость в нашем смысле. понятное дело, что при таком определении знаменитость на вечеринке может быть только одна, а может её и вообще не быть.
отношения участников вечеринки заданы в виде квадратной таблицы, где ячейка (i, j) содержит 1, если i знает j и 0, если не знает.
спрашивается, как за O(N), где N - количество народа на вечеринке, найти, есть ли знаменитость, и кто она.
все ответы по умолчанию будут скриниться, затем по мере возможности в реальном времени расскриниваться (за исключением ответов, содержащих правильное решение, которые останутся заскриненными несколько дней, чтобы у остальных было время подумать).
(я сам задачку услышал вчера, немного поломал голову и плюнул, а сегодня из глубин подсознания сам собой всплыл ответ)
Update: всё расскриниваю ввиду большого количества правильных ответов. чуть попозже выкину обзор типов ответов.
большая вечеринка. party по-нашему. кто-то кого-то знает, кто-то кого-то нет. отношение "знает" не обязательно симметрично - А может знать Б, а Б - не знать А. особенно "несимметричны" знаменитости. знаменитость определяется как чувак, которого все знают, но который не знает никого. жосткое такое определение, но нужно для удобства задания задачки. то есть если чувак хоть кого-то знает, то он уже не знаменитость в нашем смысле. понятное дело, что при таком определении знаменитость на вечеринке может быть только одна, а может её и вообще не быть.
отношения участников вечеринки заданы в виде квадратной таблицы, где ячейка (i, j) содержит 1, если i знает j и 0, если не знает.
спрашивается, как за O(N), где N - количество народа на вечеринке, найти, есть ли знаменитость, и кто она.
все ответы по умолчанию будут скриниться, затем по мере возможности в реальном времени расскриниваться (за исключением ответов, содержащих правильное решение, которые останутся заскриненными несколько дней, чтобы у остальных было время подумать).
(я сам задачку услышал вчера, немного поломал голову и плюнул, а сегодня из глубин подсознания сам собой всплыл ответ)
Update: всё расскриниваю ввиду большого количества правильных ответов. чуть попозже выкину обзор типов ответов.
(no subject)
Date: 2007-04-20 10:13 am (UTC)Хорошая задачка, да :))
(no subject)
Date: 2007-04-20 10:19 am (UTC)Проблема в том, что вот эту оценку сложности (О большое от N) я никогда толком не понимал :)
(no subject)
Date: 2007-04-20 10:21 am (UTC)Если эта сумма = N-1, он соответствует тому, кого знают все. В этом случае проверить, стоит ли в сумме его колонки 0. Если это так, то решение найдено. Если это не так, то знаменитости не было.
(no subject)
Date: 2007-04-20 10:22 am (UTC)(no subject)
Date: 2007-04-20 10:24 am (UTC)Пусть Ai = sum(2^T(i,j)){j=1..N} - число, образованное рядом i
Bi = sum(2^T(j,i)){j=1..N} - число, образованное колонкой номер i
Тогда Если Ai - степень двойки, а Bi = (2^N)-1, то i - знаменитость.
(no subject)
Date: 2007-04-20 10:27 am (UTC)(no subject)
Date: 2007-04-20 10:40 am (UTC)(no subject)
Date: 2007-04-20 10:47 am (UTC)Сначала линейно пройтись по списку всех "кандидатов". Если первый и второй друг друга знают или не знают - исключить обоих. Если 1-й несимметрично знает 2-го или наоборот - исключить одного.
Повторять, пока не останется только один.
Проверить, что в его строке нули, а столбце единицы.
(no subject)
Date: 2007-04-20 11:12 am (UTC)(no subject)
(no subject)
Date: 2007-04-20 11:27 am (UTC)Во-первых, в процессе нахождения суммы для ряда можно прекращать суммирование, если обнаружен хотя бы один 0 (хотя бы один человек не знает i, значит, сумма точно меньше N-1).
Во-вторых, для ряда с суммой N-1 (меня знают все) можно сразу проверить, равна ли сумма в соответствующей колонке 0 (я не знаю никого); если это так, то решение найдено, если не так, то знаменитости на вечеринке нет, потому что все остальные знают как минимум одного человека, и на этом поиск прекращается.
И, кажется, я рядами называла колонки и наоборот, хотя сути это не меняет.
Суммирования тоже можно не делать - достаточно пробежаться по каждому ряду в поисках нулей не в позиции (i,i), выбирая первый, в котором получится дойти до конца.
(no subject)
Date: 2007-04-20 11:48 am (UTC)Или это не проходит из-за O(N) ?
(no subject)
Date: 2007-04-20 12:08 pm (UTC)Считаем сумму по каждой строке и каждому столбцу.
Если сумма по n-й строке 0, а по n-ному столбцу N-1, то это оно и есть. Только я не знаю что такое O(N) ;).
(no subject)
Date: 2007-04-20 01:23 pm (UTC)так что уточняйте условие
(no subject)
Date: 2007-04-20 02:39 pm (UTC)так как надо просмотреть O(N^2) данных из таблички
(no subject)
Date: 2007-04-20 03:17 pm (UTC)// We assume that party[i,i] == 1
//
int solve(bool[,] party)
{
   int k = 0;
   while (j < N)
   {
      if (party[i, j] == 0)
      {
         j++;
         k = i;
      }
      if (party[i, j] == 1)
         i++;
      if (i == N - 1)
         return ((k-th row is all 0s except j-th element) && (j-th column is all 1s)) ? j : -1;
   }
   return -1;
}
Я не компилировал ;)) Иными словами просто змейкой спускаемся из(0,0). если (i,j)=0, то сдвигаемся вправо, если 1, то спускаемся вниз. Если достигли последней строчки, проверяемем, что это звезда (знаменитость?): стоблец из единиц, и предыдущая и строчка с которой мы начали спускаться по этой колонке состоит из нулей.
О задачке узнал от
(no subject)
Date: 2007-04-20 03:40 pm (UTC)int starIndex = -1;
for(int i=0; i< N; i++){
if(NA[i, i+1] == 1){
continue;
}else{
int j = i+2;
while(NA[i,j] == 0 & j
int starIndex = -1;
for(int i=0; i< N; i++){
if(NA[i, i+1] == 1){
continue;
}else{
int j = i+2;
while(NA[i,j] == 0 & j <N){
j++;
}
if(j == N){
Console.Write("Possible star");
starIndex = i;
break;
}else{
i = j;
}
}
}
Где N - длина таблицы (нужно учитывать, что таблица квадратная), а NA массив NxN с данными 1 или 0. проверка звезды занимает O(N) -> так что сложность O(2N) т.е. O(N).
(no subject)
Date: 2007-04-20 04:21 pm (UTC)Когда кончатся строчки - продолжаем опять с первой строчки по тому же принципу, сохраняя текущую колонку, пока или не выйдем за число колонок, или же не просмотрим с положительным результатом одну колонку во всех строчках. В первом случае знаменитости нет, во втором случае номер колонки указывает на знаменитость. Вроде как, максимальное количество просмотренных ячеек получается 8*N.
(no subject)
Date: 2007-04-20 05:18 pm (UTC)(no subject)
Date: 2007-04-20 05:49 pm (UTC)(no subject)
Date: 2007-04-20 05:52 pm (UTC)(no subject)
Date: 2007-04-20 05:54 pm (UTC)(no subject)
Date: 2007-04-20 05:57 pm (UTC)(no subject)
Date: 2007-04-20 05:57 pm (UTC)(no subject)
Date: 2007-04-20 05:59 pm (UTC)Пускай число отношений "один человек знает другого" - M. 0≤M≤N2. Пусть k = M/N. 0≤k≤N.
Создадим массив из N булевых - кандидатов в знаменитости. Инициализируем его всеми true.
Выберем случайного человека и исключим из кандидатов во-первых, всех, кого он не знает, а во-вторых, всех, кто знает его. Эта процедура займет O(N) операций. В среднем человек знают k людей, а не знают N-k; доля тех людей, кого он не знает, среди всех 1-k/N. В среднем человека знают k людей; доля тех, кто знает его, среди всех k/N. Мы умножили число кандидатов на (1-k/N)*(k/N).
Функция f(k) = (1-k/N)*(k/N) имеет минимум 0 (при k=0 или k=N) и максимум 1/4 (при k=N/2). Мы сокращаем число кандидатов в 4 раза.
Будем повторять, пока число кандидатов не станет нулем или единицей.