Задать вопрос
shatov
@shatov
1C

Как решить данную задачу?

В кругу стоят N человек, пронумерованных от 1 до N. При ведении счета по кругу вычёркивается каждый второй человек, пока не останется один. Составить программу, моделирующую процесс.
У меня получается написать задачу где он удаляет каждый второй элемент. Например, есть список из 10 элементов (1....10). После удаления каждого второго элемента остается: 2 4 6 8 10. Не знаю как сделать чтоб он по новой удалял каждый второй элемент.
  • Вопрос задан
  • 16506 просмотров
Подписаться 3 Оценить 1 комментарий
Пригласить эксперта
Ответы на вопрос 8
Lerg
@Lerg
Defold, Corona, Lua, GameDev
Вот вам на Lua, только ответ всё время 1 получается.
Думаю, сможете воспроизвести на нужном языке.
repl.it/40O
Ответ написан
Комментировать
Neuroware
@Neuroware
Программист в свободное от работы время
Используй C# коллекцию List и формируй новую коллекцию вместо удаления элементов в старой, тогда сможешь повторить все тоже с новой коллекцией. Желательно использовать рекурсию, это упростит код.
Ответ написан
Комментировать
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
CAMOKPYT Sergey Lerg круто, такое простое условие, и всё равно "при ведении счета по кругу" не осилили.
Садитесь оба, два.
И, да, Альберт домашние задания делайте сами, это в ваших же интересах.
Ответ написан
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Удалять надо по кругу, то есть для {1, 2, 3, 4, 5}
Пропускаем первого, удаляем второго - {1, 3, 4, 5}
Пропускаем следующего (3), удаляем (4) - {1, 3, 5}
Пропускаем следующего (5), переходим на следующий круг, удаляем (1) - {3, 5}
Пропускаем следующего (3), удаляем (5) - {3}
Ответ написан
Комментировать
aush
@aush
С произвольным шагом:

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        Console.WriteLine(GetLastStanding(11, 4));
    }

    static int GetLastStanding(int n, int step)
    {
        var items = Enumerable.Range(0, n)
                        .Select(position => new Item { Position = position }).ToArray();
        var i = 0;
        var stepCounter = 0;
        var nCounter = n;
        while (nCounter > 1)
        {
            if (!items[i].Marked && ++stepCounter == step)
            {
                stepCounter = 0;
                items[i].Marked = true;
                --nCounter;
                Console.WriteLine(string.Join(", ",
                    items.Select(item => item.Marked ?
                        "_" : (item.Position + 1).ToString())));
            }

            i = (i + 1) % n;
        }
        return items.Single(item => !item.Marked).Position;
    }

    struct Item
    {
        public int Position;
        public bool Marked;
    }
}
Ответ написан
Комментировать
lam0x86
@lam0x86
Не слушай их всех =)
Наверняка, преподаватель хочет видеть решение с замкнутым связным списком. Что-то вроде такого:
class Program
    {
        static void Main()
        {
            var personList = GenerateList(15); // personList указывает на первого человека в списке

            PrintList(personList);

            var p = personList;
            while (p != p.NextPerson) // пока человек не остался один в списке
            {
                #region Этот кусок для корректного вывода списка на экран. Если вывод не нужен, можно убрать
                if (personList == p.NextPerson)
                {
                    personList = p.NextPerson.NextPerson;
                }
                #endregion

                // <ВсяСоль>
                p = p.NextPerson = p.NextPerson.NextPerson;
                // </ВсяСоль>

                // Если убрать верхний регион, то может возникнуть ситуация, когда personList указывает на 
                // человека, который был удалён из списка. Возникнет бесконечный цикл.
                PrintList(personList);
            }
        }

        // Вывод списка на консоль
        private static void PrintList(Person personList)
        {
            var p = personList;
            do
            {
                System.Console.Out.Write(p.SequenceNumber);
                System.Console.Out.Write(" ");
                p = p.NextPerson;
            } while (p != personList);
            System.Console.Out.WriteLine();
        }

        // Генерация списка
        private static Person GenerateList(int n)
        {
            // Начинаем с последнего человека
            var currentPerson = new Person(n);
            var lastPerson = currentPerson;

            // затем создаём N-1 человек, указывая его порядковый номер и следующего за ним человека
            for (int i = n - 1; i > 0; i--)
            {
                currentPerson = new Person(i) { NextPerson = currentPerson };
            }

            // последнего человека закольцовываем с первым
            lastPerson.NextPerson = currentPerson;
            return currentPerson;
        }
    }

    class Person
    {
        public Person(int sequenceNumber)
        {
            SequenceNumber = sequenceNumber;
        }

        public int SequenceNumber { get; private set; }

        public Person NextPerson { get; set; }
    }
Ответ написан
Комментировать
DmitryITWorksMakarov
@DmitryITWorksMakarov
Еще один вариант со связанным списком
using System;
using System.Collections.Generic;
using System.Linq;

namespace throughOneKill
{
    class Program
    {
        static void Main(string[] args)
        {
            int N = 10;

            var list = new LinkedList<int>(Enumerable.Range(1, N));
            Console.WriteLine(string.Join(" ", list));
            var currentItem = list.First;
            while (list.Count != 1)
            {
                list.Remove(currentItem.Next ?? list.First);
                currentItem = currentItem.Next ?? list.First;
            }
            Console.WriteLine(list.First.Value);

            Console.ReadKey();
        }
    }
}
Ответ написан
Комментировать
@Sterk
Программист
вот самое простое решение

var list = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
PrintList(list);
bool delete = false;
while (list.Count > 1)
{
    for (int i = 0; i < list.Count; i++)
    {
        if (delete) list.RemoveAt(i--);
        delete = !delete;
    }
    PrintList(list);
}
Console.Read();

функция печати
static void PrintList(IEnumerable<int> list)
{
    foreach (var item in list)
        Console.Write("{0} ", item);
    Console.WriteLine();
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы