论坛: 编程破解 标题: 一个问题三个C程序的解法,那个是最好的? 复制本贴地址    
作者: lida1818 [lida1818]    论坛用户   登录
题目:如何实现n个人围成圈,从头开始数,数到7便出列,最后剩下谁。

现有如下:

1。

#include "stdafx.h"
#define M  100  //一共有100个人
#define N  7    //数到7就出列

int a[M],b[M];

void eliminate(int s,int m)
{
    static n = 0;
    int i,j,k;

    if(m == 1)
        return;
    for(i=0,j=s,k=m-1;i<N;++i)  //寻找被压缩元素
    {
        if(++j>k)
            j=0;
    }

    //标记被压缩成员的编号
    b[n++] = j ? a[j-1] : a[k];

    //压缩剩余的数据
    if(j)
        for(i=--j;i<k;++i)
        {
            a[i] = a[i+1];
        }
   
    eliminate(j,k);


int main(int argc, char* argv[])
{
    int i;
    for(i=0;i<M;++i)  //初始化数据
    {
        a[i] = i+1;
    }
    eliminate(0,M);
    for(i=0;i<M-1;++i)  //输出
    {
        printf("%d  ",b[i]);
    }
    printf("%d\n",a[0]);
    //暂停
    getchar();
    return 0;
}



=============================

2。

#include <iostream.h>
#include <iomanip.h>

struct jose  //小孩结点
{
  int code ;
  jose* next ;
};

void main()
{
//赋初值
int numOFBoys , interval ;
cout << "please input the number of boys,\n" //小孩数
      <<"      interval of counting : \n" ;  //数小孩个数
cin >> numOFBoys >> interval ;

//建立小孩结构数组
jose * pjose = new jose[numOFBoys] ;  //从堆内存分配空间
jose * pcurrent = pjose ;            //当前结点指针

//初始化数组结构:构成环链,小孩编号,输出编号
int itemsinline = 0 ; //输出项数

for(int i = 1;i<=numOFBoys;i++)
{
  pcurrent -> next = pjose + i%numOFBoys ; //链到下一个元素
  pcurrent -> code=i ;                    //小孩编号
  pcurrent = pcurrent -> next ;
  if(itemsinline++%10 == 0)
    cout <<endl ;
  cout << setw(4) << i ;
}                //pcurrent 此时等于pjose
itemsinline = 0;

jose * pivot ;    //链表哨兵
pcurrent = &pjose[numOFBoys-1] ; //下一个就是数组第一个元素pjose[0]

while(pcurrent->next != pcurrent)  //处理未获胜的所有小孩
{
  for(int j =0 ;j<interval;j++) //数interval个小孩
  {
    pivot = pcurrent ;
    pcurrent = pivot->next ;
  }

  if(itemsinline ++ % 10 ==0)  //输出小孩
    cout << endl ;
  cout << setw(4)<<pcurrent->code ;
  pivot->next = pcurrent->next ;  //小孩脱链
  pcurrent = pivot ;
}
 
cout << "\n\nthe winner is"
      << pcurrent->code<<endl ; //获胜者

delete[]pjose;          //返还堆空间
}

===================================

3。

b,c为两个计数器,c是报7出列计数器,b是计算出列人数等于总人数则跳出循环结束程序打印最后一个出列的序号。

TC 2。0下通过

main()
{
int* s;
int i=0,b=0,c=0,a;
printf("输入总人数:");
scanf("%d",&a);  //输入队列的总人数
s=(int *)malloc(sizeof(int)*a);
for(i=0;i<a;i++)s[i]=1;  //初始化,令S[]数组全部为1
i=0;
while(b!=a){
        if (s[i]==1){
                    if (c==6){
                              s[i]=0;//出列则标志为0
                              b++;
                              c=0;
                              }
                    else c++;
                              i++;}
        else i++;
        if (i==a)i=0;
                              }
        printf("最后一个出列的人的序号是:");
        printf("%d",i);    //打印最后一个出列的序号
        }



请教各位以上三种方法那种最好?原因是什么?望详说,谢谢!


[此贴被 烟雨平生(lida1818) 在 03月12日10时30分 编辑过]

地主 发表时间: 04-03-11 22:17

回复: afan271314 [afan271314]   论坛用户   登录
你说少了吧  我看书上是N个小孩围成一个圈  不过我没看懂 





[此贴被 真爱有限(afan271314) 在 03月12日09时00分 编辑过]

B1层 发表时间: 04-03-12 08:48

回复: lovejiang [lovejiang]   论坛用户   登录
单向循环链表来做我觉得那样做要好一些


[此贴被 lovejiang(lovejiang) 在 03月12日15时23分 编辑过]


[此贴被 lovejiang(lovejiang) 在 03月13日19时07分 编辑过]

B2层 发表时间: 04-03-12 15:19

回复: sniper167 [sniper167]   论坛用户   登录
老潭那本答案书上的方法不错

B3层 发表时间: 04-03-13 18:40

回复: yuanrulai [yuanrulai]   论坛用户   登录
我只用过第三个算法

B4层 发表时间: 04-05-28 20:18

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号