zoukankan      html  css  js  c++  java
  • 约瑟夫问题两种实现方式

    数组版本

    #include<stdio.h>
    #include <stdlib.h>
    
    
    main(){
    	
        
        int len;
        int pace;
        int time;
        int start;
        printf("请输入人数:
    ");
        scanf("%d",&len);
        if(len<=0)
        {
        	printf("输入错误,程序终止!
    ");
        	exit(-1);
    	}
        
        
        int *p=(int*)malloc(len*sizeof(int));
         printf("请输入步长:
    ");
        scanf("%d",&pace);
       
        if(pace==0)
        {
        	printf("输入错误,重新输入!
    ");
        	exit(-1);
    	}
        //if(pace==0)
    
        printf("请输入进行轮数:
    ");
        scanf("%d",&time);
        printf("请输入您想从那个元素开始:
    ");
        scanf("%d",&start);
        if(start==0)
        {
        	printf("输入错误,请重新输入:
    ");
        	exit(-1);
    	}
        
        
        	
        for(int i=0;i<len;i++){*(p+i) = 1;}   // 数组初始化,1:表示为活着;0:表示自杀
    
        int leftCount = len;                // 计数器leftCount:计数剩下的人
        int index = start-1,count = 0;            // 1.数组下标index;2.循环计数器count
        
         
         
        while(leftCount>(len-time))//从规定元素起点开始 
    	{                            // 当还剩下n个结束
    
            if(*(p+index) == 1){ 
                count++; 
                if(pace== count){             // 计数到3,1.自杀;2.循环计数器count重新开始计数;3.计数器leftCount减1
                    *(p+index) = 0;
                    count = 0;
                    leftCount--;
                }
            }
            index++;
    
            if(index == len){index = 0;}    // 当到数组尾,数组下标index置零,重新开始
        }
    
        for(int j=0;j<len;j++){             // 输出结果
            if(1 == *(p+j)){ printf("剩下的人为第%d个
    ",j+1); }
        }
    }
    
     
    

     单向循环链表版本

    # include <stdio.h>
    # include <stdlib.h>
    typedef struct circle_list{
    	int data;
    	struct circle_list *next;
    }NODE,*PNODE;//定义节点
    PNODE creat_list(int len);//创建循环链表 
    
    void visit_list(PNODE mark,int len,int time);//遍历寻欢链表 
    PNODE  kill_list(PNODE head,int pace,int time,int len,int mark);//删除循环链表的一个给定下表的元素 
    
    
    main()
    {
    	int pace;//步长 
    	int time;//轮数 
    	int len;//循环链表的长度 
    	int index;//开始游戏的下标 
    	PNODE mark=NULL;//访问遍历链表的指针 
    	PNODE head=NULL;//创建循环链表的头 
    	int i;
    	printf("在罗马人占领乔塔帕特后,
    ");
    	printf("39 个犹太人与Josephus及他的朋友躲到一个洞中,
    ");
    	printf("39个犹太人决定宁愿死也不要被敌人抓到,
    ");
    	printf("于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,
    ");
    	printf("每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
    ");
    	printf("现在您就是约瑟夫,为了活下去,您需要预测怎样才能活到最后
    ");
    	printf("而此时您得到了一个神奇的程序,请借助它,活下去!
    ");
        printf("********************************************************************************
    ");
    	printf("欢迎来到约瑟夫问题,游戏开始!
    ");
    
        printf("请输入总人数:
    ");
        scanf("%d",&len);
        if(len==0)
        {
        	printf("输入错误,程序结束
    ");
        	exit(-1);
    	}
    	head=creat_list(len);//创建链表 
    	
    	
    	printf("请输入您想从第几个人开始:
    ");
        scanf("%d",&index);
    	
    	printf("请输入步长(每经过几个人杀一个人:)
    ");
    	scanf("%d",&pace);
        printf("请输入进行的第几轮:
    ");
        scanf("%d",&time);
       
        mark=kill_list(head,pace,time,len,index);//杀人并提供访问遍历链表的下标 
        visit_list(mark, len,time);//遍历链表 
        
        
        
    	
    	
    }
    
    PNODE creat_list(int len)
    {
    	PNODE head=NULL;
    	PNODE  p;
    	PNODE q;
    	int i;
    
    	p=(PNODE)malloc(sizeof(NODE));
    	if(p==NULL)
    	{
    		printf("内存分配失败!
    ");
    		exit(-1);
    	}
    	head=p;
    	p->data=1;//创建头结点 并且将它的数据域置为1 
    	
    	for(i=2;i<=len;i++)//创建其他节点并依次将这些节点挂在尾部 
    	{
    		q=(PNODE)malloc(sizeof(NODE));
    		if(q==NULL)
    		{
    			printf("内存分配失败!
    ");
    			exit(-1);
    		}
    		q->data=i;//依次给节点数据域赋值,作为“人”的序号 
    		p->next=q;
    		p=q;//让p永远指向链表的尾部 
    		
    	}
    	p->next=head;//首尾相连 
    	return head;//返回头结点地址以便访问 
    }
    void visit_list(PNODE mark,int len,int time)//遍历循环链表 
    {
    	
    	PNODE p=mark;//从标记开始进行循环 
    	
    	int count=0;
    	printf("幸存下来人的序号为:
    ");
    do
    	{
    		printf("%d ",p->data);//依次输出未被删除节点的序号 
    		p=p->next;
    	}
    while(p!=mark);//当没有循环够一圈 
    	
    
    	 printf("
    ");
    	
    }
    
    
    PNODE  kill_list(PNODE head,int pace,int time,int len,int index)
    {
    	int leftcount=len;//活着的人数 
    	PNODE p=head;
    	PNODE mark=NULL;//留下以便访问的地址 
    	PNODE remain=NULL;//作为用来防止内存泄漏的媒介 
    	int count=0;//循环次数 
    	int count1=0;//从开始游戏的那个人开始循环次数 
    	while(leftcount>(len-time))
    	{
    		count++;
    		if(count>=index)//当过了要开始下表才开始杀人 
    		{
    			count1++;
    			if(count1%(pace-1)==0)//当循环到要删除的那个节点的上一个节点才开始删除下一个节点 
    			{
    				mark=p;//不断刷新下表让它永远是最后留在链表中节点的地址即mark所指向的那个节点删到最后一定要存在 
    				remain=p->next;
    				p->next=p->next->next;//改变指针指向来删除节点 
    				free(remain);
    				leftcount--;//人数减少一位 
    				
    				
    			}
    		}
    		p=p->next;//遍历条件 
    	}
    	return mark;
    }
    

      

  • 相关阅读:
    程序员怎么提高英语阅读水平【转】
    Linux后台执行【转】
    pcre安装错误的解决方法
    编译PHP错误:undefined reference to `ts_resource_ex'
    apache2启动时共享库libpcre找不到
    设置Ubuntu的IP地址
    vsftp 的应用
    用Python实现动态的切换桌面背景
    DNN 4.x CodeSmith模板
    如何在DNN中使用Google Analytics
  • 原文地址:https://www.cnblogs.com/mengxiaoleng/p/11197294.html
Copyright © 2011-2022 走看看