循环链表问题

1,约瑟夫问题

问题:15个人排成一圈,并给他们编号1~15,现在从1号开始报数,报数字4的人退出队列,余下的人从退出者下一个位置开始继续刚才的报数,直到整个队列中只剩下一个人为止。求这个人的编号。

分析:1,如果有N个人,需要比较操作N-1次操作。

2,设定最后N个人和N-1个人的结果分别是k(n)和k(n-1),则k(n) = (k(n-1) +m)%N (解释,每次移动m次,取N的余数目的是保证结果总在【0,N),N由每次操作的人数决定),所以我们可以得到公式F(n) = (F(n-1) + m) % N

F(n-1) = (F(n-2) + m) %(N-1)

F(1) = 0 那么结果现在就变成了 求F(n) (从F(1)递推求)。

#include <stdio.h>
int main()
{
  int n, m, i, s=0;
  printf ("N M = "); scanf("%d%d", &n, &m);
  for (i=2; i<=n; i++) s=(s+m)%i;
  printf ("The winner is %d\n", s+1);
}

 

2,拉丁方阵

问题:如果用从1开始的N个连续正整数排成N*N的方阵,且每一行和每一列没有重复的数,就称其为一个N阶拉丁方阵。因为这样的方阵最早填充的是拉丁字母,因此得名拉丁方阵。例如下面给出的是一个4阶拉丁方阵:

1 2 3 4

2 3 4 1

3 4 1 2

4 1 2 3

分析:用连续【1~N】填充N*N数组,确保行列没有重复,且连续。

要保证行和列都符合条件,同时考虑会比较乱,那么先考虑确保每一行是正确的。观察上面的示例,可以看出第二行开始的编号是从上一行第二个开始,然后顺序赋值的,而去过我们的行赋值是这样的话,那么列就自然保证了。

转载于:https://www.cnblogs.com/sharpfeng/archive/2011/03/03/1969903.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值