约瑟夫问题

约瑟夫问题

Time Limit: 1000MS Memory limit: 65536K

题目描述

n个人想玩残酷的死亡游戏,游戏规则如下: 

n个人进行编号,分别从1到n,排成一个圈,顺时针从1开始数到m,数到m的人被杀,剩下的人继续游戏,活到最后的一个人是胜利者。

请输出最后一个人的编号。

输入

输入n和m值。

输出

输出胜利者的编号。

示例输入

5 3

示例输出

4

提示

第一轮:3被杀第二轮:1被杀第三轮:5被杀第四轮:2被杀

#include <stdio.h>

int IsEnd(int a[],int n);//测试就剩一个入?如果是。就返回序号。否则返回0


int main()
{
	int n,m;
	int a[100];
	int i=0,j=0;
	int t;
	scanf("%d %d",&n,&m);
	for(i=1; i<=n; i++)//数值便是他们各自的编号
	{
		a[i]=i;
	}
	i=0;
	while( (t=IsEnd(a,n)) == 0)//当剩下人数超过1个时
	{
		i++;
		if(i == n+1)//数到最好一个人后从头循环
			i=1;
		if( a[i] != 0)//如果没有被杀掉
		{
			j++;
			if(j % m == 0)//没有被杀掉的数到m
				a[i] = 0;//值为0,表示被杀掉
		}
	}
	printf("%d\n",a[t]);

	return 0;
}

int IsEnd(int a[],int n)
{
	int t=0,m=0;
	for(int i=1; i<=n; i++)
	{
		if(a[i] != 0)
		{
			t=i;
			m++;
		}
		if(m > 1)
			return 0;
	}
	return t;
}

//链表做法

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <math.h>  
  
typedef struct Node{  
    int data;  
    struct Node *next;  
}Node, *Link;  
  
Link create(int n){  
    Link head, p, tail;  
    int i;  
    tail = head = (Link)malloc(sizeof(Node));  
    head->next = NULL; head->data = 1;  
    for(i=1; i<n; i++){  
        p = (Link)malloc(sizeof(Node));  
        p->data = i+1;  
        //p->next = tail->next;  
        //tail->next = p;  
        tail->next = p;  
        tail = p;  
    }  
    p->next = head;  
    return head;  
}  
  
void print(Link head){  
    Link p = head->next;  
    while(p->next){  
        printf("%d ", p->data);  
        p = p->next;  
    }  
    printf("%d\n", p->data);  
}  
  
int main(){  
    Link head, tail, p;  
    int n, m, i=0;  
    scanf("%d %d", &n, &m);  
    tail = p = head = create(n);  
    while(tail->next != head){  
        if(tail->next == head) break;  
        tail = tail->next;  
    }  
    do{  
        i++;  
        if(i % m == 0) {tail->next = p->next; free(p); p = tail->next;}  
        else{ tail = tail->next; p = p->next;  
        }  
    }while(p->next != p);  
    printf("%d\n", p->data);  
    return 0;  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值