【原题】
N个人围成一圈,进行编号,记为1到N号。
船长说,只有一个人可以留在船上。从一号开始传一瓶毒药,每隔一个人,接到毒药的人就必须喝下它。第一圈1号3号5号会纷纷喝毒药倒下...由于大家围成一个圈,所以进行到最后,必然只有一个人可以活下来。
活下来的人是几号?
【解题过程】
反正也没看出来有什么规律,就干脆写个程序把结果打印出来看一下,程序如下:
// kill_person.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
typedef unsigned long DWORD;
typedef struct _T_Node
{
DWORD dw_val;
bool b_killed;
struct _T_Node* pt_pre;
struct _T_Node* pt_next;
}T_Node;
void Calc(DWORD dw_num)
{
T_Node at_node[1000];
DWORD dw_left;
DWORD i;
T_Node* pt_cur;
// set default value -------
dw_left = dw_num;
// init -------
for (i = 0; i < dw_num; i++)
{
at_node[i].b_killed = false;
at_node[i].dw_val = i + 1;
}
for (i = 0; i < dw_num - 1; i++)
{
at_node[i].pt_next = &at_node[i + 1];
}
at_node[dw_num - 1].pt_next = &at_node[0];
for (i = 1; i < dw_num; i++)
{
at_node[i].pt_pre = &at_node[i - 1];
}
at_node[0].pt_pre = &at_node[dw_num - 1];
// calc ---------
pt_cur = &at_node[0];
while (dw_left > 1)
{
// kill
pt_cur->b_killed = true;
dw_left--;
(*(pt_cur->pt_pre)).pt_next = pt_cur->pt_next;
(*(pt_cur->pt_next)).pt_pre = pt_cur->pt_pre;
pt_cur = pt_cur->pt_next;
pt_cur = pt_cur->pt_next;
}
// show result --------
for (i = 0; i < dw_num; i++)
{
if (false == at_node[i].b_killed)
{
printf("一共%d个人,第%d个人活了下来\r\n", dw_num, at_node[i].dw_val);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD i;
for (i = 2; i < 100; i++)
{
Calc(i);
}
getchar();
return 0;
}
打印出来以后,发现结果还是有规律的,截张图:
当然后面的结果是自己根据规律总结的,不算是严格的求解: