Поиск:

Ответ в темуСоздание новой темы Создание опроса
> задачи типа считалки 
:(
    Опции темы
FireSnake
Дата 16.12.2006, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 15.9.2006
Где: Украина, Донецк

Репутация: нет
Всего: 1



Кто знает как решаются задачи типа "считалки"? Т.е. есть от 1 до N людей (по кругу) где каждый K-ый из оставшихся выбывает из строя и необходимо найти последнего оставшегося или вывести список выбывания(в зависимоти от условия).
PM MAIL ICQ   Вверх
_Y_
Дата 16.12.2006, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Я бы делал это в лоб:

1) В Java загоняем  N персонажей в Vector, в языках не имеющих такой фичи придется использовать массив, но тогда процедура удаления элемента будет несколько длиннее. Длина массива на данный момент D = N
2) Присваиваем M = K
3) if(M <= D) goto 6
4) M = M - D
5) goto 3
6) Выводим информацию об удалении персонажа стоящено, на данный момент, под номером M и удаляем его из массива. Если это не Vector пишем процедуру смещения всех стоящих после него на шаг
влево и уменьшаем размер массива на единицу. Если Vector, все это делается в один шаг. Так или иначе получается D = D - 1
7) if(D = 1) goto 10
8) D = D + K - 1 (отнимать единицу здесь нужно т.к. члены массива сдвинулись и номер выбывшего уже занят кем-то еще)
9) goto 3
10) Выводим информацию о последнем оставшемся
11) Идем пить пиво

Кажется нигде не ошибся smile 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
esperant0
Дата 16.12.2006, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



В лоб задачу не рашают.

Решение задачи аналитически есть у Кнута в конкретной математике.

А любители решить в лоб, могут решить задачу длЯ 10^100 человек.


--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
levalex
Дата 16.12.2006, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 12.12.2006

Репутация: нет
Всего: нет



N - количество детей.
T - номер оставшегося

N  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 ...
T  1  1  3   1  3  5  7  1  3  5   7   9  11 13 15  1  3  ...  
 
Эксперементальным путем устанавливаем закономерность:
t(1)=1
t(2*n)=2*t(n)-1 при n>=1
t(2*n+1)=2*t(n)-1 при n>=1
Если n=2^n(два в степени n)+q? где 2^m - наибольшая степень 2, не превосходящая N, a q - разность N- 2^m, то номер оставшегося ребенка вычисляется по формуле: t(2^m+q)=2*q+1 при m>=0 и 0<=q<=2^m.

По крайней мере так написанов С. Окулов "Основы программирования".
PM MAIL ICQ   Вверх
_Y_
Дата 17.12.2006, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Цитата(esperant0 @ 16.12.2006,  16:49)
любители решить в лоб, могут решить задачу длЯ 10^100 человек.

Все так, решение "в лоб" для большого числа персонажей заставит комп серьезно потрудиться. 

Но ведь предложенное аналитическое решение дает только номер последнего оставшегося. FireSnake же спрашивал и про то, как получить список выбывания.

Предложите другой алгоритм пересортировки списка. Он, возможно, будет работать быстрее моего (я все-таки этой задачей не загружался, а предложил то, что лежит на поверхности), но все равно займет значительное время.

ЗЫ: А 10^100 человек не бываетsmile Максимум чуть больше 6*10^9.  smile  Бактерий наверное бывает, но они врядли в детские считалки играют smile и моим алгоритмом уж точно пользоваться не будут

Это сообщение отредактировал(а) _Y_ - 17.12.2006, 11:44


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
SoWa
Дата 17.12.2006, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Харекришна
****


Профиль
Группа: Комодератор
Сообщений: 2422
Регистрация: 18.10.2004

Репутация: 6
Всего: 74



Плавно съехали с задачи про считалку.
5859267andrey, комбинаторика...  smile 
Теперь о считалке- периодическую функцию придумай, например на основе синуса. По ней и отсеивай людей. по оси абсцисс откладывай число, а по ординат- человека. При этом sup этой функции будет равен числу людей. К примеру функция 
Код

y=n*sin(x)



--------------------
Всем добра smile
PM MAIL ICQ   Вверх
maxim1000
Дата 18.12.2006, 01:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



вопрос по размену выделил в одну тему: http://forum.vingrad.ru/topic-127865.html


--------------------
qqq
PM WWW   Вверх
esperant0
Дата 18.12.2006, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 714
Регистрация: 20.5.2005

Репутация: 4
Всего: 14



Цитата(SoWa @ 17.12.2006,  20:33)
Плавно съехали с задачи про считалку.
5859267andrey, комбинаторика...  smile 
Теперь о считалке- периодическую функцию придумай, например на основе синуса. По ней и отсеивай людей. по оси абсцисс откладывай число, а по ординат- человека. При этом sup этой функции будет равен числу людей. К примеру функция 
Код

y=n*sin(x)

Идея с синусом кажется не верной. Может поделитесь доказательством, дабы убить сомнения?





--------------------
 
 Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer 

Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором  а затем стерто и которое он - пользователь не мог видеть. 
PM MAIL   Вверх
SoWa
Дата 18.12.2006, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Харекришна
****


Профиль
Группа: Комодератор
Сообщений: 2422
Регистрация: 18.10.2004

Репутация: 6
Всего: 74



что именно кажется не верным?
Начинаем.
Синусойда высотой "количество человек".
Берем, допустим её первые несколько периодов.Например от нуля до 20*pi.
Делим это на количество человек. Получаем шаг.
Идем с этим шагом по абсциссам и получаем ординаты. Пусть есть массив участников. Присвоим каждому целое значение на оси ординат. На каждый шаг получаем значение синусоиды. Находим промежуток целых значений, в котором лежит это значение. Вычеркиваем из массива. Так делаем пока не останется один участник.
Единственная проблемма- сосчитать шаг, чтобы два значения синусоиды за два шага не попадали в один промежуток по оси ординат. Но это, ИМХО, дело техники.

СУВ, SoWa


--------------------
Всем добра smile
PM MAIL ICQ   Вверх
Dov
Дата 22.12.2006, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: нет
Всего: 88



Пример такой задачи на С++.
Здесь.




--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
FireSnake
Дата 17.1.2007, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 15.9.2006
Где: Украина, Донецк

Репутация: нет
Всего: 1



Что б никто не спорил относительно ограничений - вот эта задача:

on-line judge

Кто получит АС поделитесь своими соображениямиsmile
PM MAIL ICQ   Вверх
Dov
Дата 18.1.2007, 02:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: нет
Всего: 88



Цитата(FireSnake @  17.1.2007,  17:05 Найти цитируемый пост)
Кто получит АС поделитесь своими соображениями

FireSnake, я уже поделился, смотри ссылку выше.

Результат работы программы:
Код
Kolxozniki:
3 1 5 2 4

Press ENTER to quit...



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
FireSnake
Дата 2.2.2007, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 15.9.2006
Где: Украина, Донецк

Репутация: нет
Всего: 1



Цитата

Ограничение времени: 1.0 секунды
N (1 ≤ N ≤ 100000)

PM MAIL ICQ   Вверх
Lomir
Дата 8.2.2007, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 30.1.2007
Где: Lithuania::Kaunas

Репутация: нет
Всего: 1



Я использовал Skip-List с соотношением 10/10000.
Список из 10 элементов, а в списке масив из из 10000 элементов (чтобы ускорить удоление). Время работы где-то O(N*log n*log n) (0.671 сек).

Код

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <assert.h>

#define FOR(i,to) for (int i = 0; i < int(to); ++i)
#define FOR1(i,to) for (int i = 1; i < int(to); ++i)
#define FORN(i,from,to) for (int i = (from); i < int(to); ++i)
#define SZ(c) int((c).size())
#define PB push_back
#define ALL(a) (a).begin(), (a).end()
#define FREE(a) memset(a, 0, sizeof a)

using namespace std;

typedef vector<int> VI;
typedef vector<bool> VB;
typedef vector<string> VS;
const double PI = acos(-1.0);
const int INF = 1e10;
const double EPS = 1e-10;

inline void openfiles()
{
    freopen("test.in", "r", stdin);
//    freopen("test.out", "w", stdout);
}
inline void print(int num)
{
    char s[9];
    int l = 0;
    while (num)
        s[l++] = num % 10, num /= 10;
    while (l--)
        putc('0' + s[l], stdout);
    putc(' ', stdout);
}

int n, k;
list<vector<int> > l;

int main () 
{
#ifndef ONLINE_JUDGE
    openfiles();
#endif
    scanf("%d %d", &n, &k);
    int capasity = 10000;
    vector<int> v;
    FOR(i,n)
    {
        v.PB(i+1);
        if (SZ(v)==capasity)
        {
            l.PB(v);
            v.clear();
        }
    }
    l.PB(v);
    int pos = k-1;
    list<vector<int> >::iterator intr = l.begin();
        while (pos>=SZ(*intr))
        {
            pos -= SZ(*intr);
            if (SZ(*intr) == 0){
                l.erase(intr++);
            }else{
                intr++;
            }
            if (intr == l.end())
                intr = l.begin();
            if (l.empty())
                break;
            if (SZ(l) == 1)
                pos = pos % SZ(*intr);
        }
    FOR(i,n)
    {
        print((*intr)[pos]);
        (*intr).erase((*intr).begin()+pos);
        pos = (pos + k-1);
        ++count;
        while (pos>=SZ(*intr))
        {
            if (SZ(*intr) == 0){
                l.erase(intr++);
            }else{
                pos -= SZ(*intr);
                intr++;
            }
            if (intr == l.end())
                intr = l.begin();
            if (l.empty() || (SZ(l) == 1 && SZ(*intr)==0))
                break;
            if (SZ(l) == 1)
                pos = pos % SZ(*intr);
        }
    }
    return 0;
}

PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0935 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.