很久以前学C时, 就弄过出局游戏(约瑟夫环), 当时很感兴趣不过只有两天时间没有做出来
今天看到了一个java也里有类似的题, 觉得用面向对象来做更合适……
题目:30个人站成一个圆圈, 从第一个人开始, 每数9个人则出局一人,一共需要出局15人,求哪些编号的人是应该出局的
下面是C#版解法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
//共30个人
int count = 30;
//需要排除的有15个人
int remainingCount = 15;
//每数9个人出局1个人
int position = 9;
//构建环形链
List<Person> list = new List<Person>();
for (int i = 1; i <= count; i++)
{
Person p = new Person()
{
Id = i,
PrevId = i == 1 ? count : i - 1,
NextId = i == count ? 1 : i + 1,
Out = false
};
list.Add(p);
}
//循环直到找出全部需要排除的人为止,
//注:为了让第一个数到的是1, 第一个出局的为9,初始定位为最后一个人(currid=30)
for (int j = 0, currId = 30; j < remainingCount; j++)
{
Person currPerson = list.Find(p => p.Id == currId);
int theNextId = 0;
for (int k = 0; k < position; k++)
{
theNextId = currPerson.NextId;
currPerson = list.Find(p => p.Id == theNextId);
}
currPerson.Out = true;
Console.WriteLine("编号为{0}的已出局", currPerson.Id);
Person prev = list.Find(p => p.Id == currPerson.PrevId);
prev.NextId = currPerson.NextId;
Person next = list.Find(p => p.Id == currPerson.NextId);
next.PrevId = currPerson.PrevId;
currId = currPerson.Id;
}
Console.ReadLine();
}
}
public class Person
{
public int Id { get; set; }
public int PrevId { get; set; }
public int NextId { get; set; }
public bool Out { get; set; }
}
}
不用面向对象的解法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
const int count = 30; //共有多少人
const int outCount = 15; //需要出局的有多少人
const int position = 9; //每数到第几个人出局
int currId = -1; //当前数到的id,因为要从下标0开始计数
bool[] arr = new bool[count];//所有元素默认为False, 正好合符没有出局
for (int i = 1; i <= outCount; i++)
{
for (int j = 1; j <= position; j++)
{
if ( ++currId>count-1 )
{
currId = 0;
}
if (arr[currId])
j--;
}
arr[currId] = true;
Console.WriteLine("第{0}个:编号为{1}的已出局", i, currId+1);
}
Console.Read();
}
}
}