版权声明:转载请声明原文链接地址,谢谢! https://blog.csdn.net/weixin_42859280/article/details/84987641
代码:
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef int datatype;
typedef int Status;
typedef int ElemType;
typedef struct Lnode
{
ElemType data;
struct Lnode *next;
}LNode;
int n;
LNode *create_LinkList(void)
{ int data ;int i;
LNode *head, *p; /* p指向当前结点 */
head= (LNode *) malloc( sizeof(LNode));
head->next=NULL; /* 创建链表的表头结点head */
cout<<"请输入囚犯总人数: ";cin>>n;
for(i=n;i>0;i--)
{data=i;p= (LNode *)malloc(sizeof(LNode));p->data=data;p->next=head->next ; head->next=p ; }
cout<<"成功建立囚犯编号: ";
return (head);
}
void X(LNode *L){
int i;
LNode *p,*q;
p= (LNode *)malloc(sizeof(LNode));
q= (LNode *)malloc(sizeof(LNode));
p=L;
q=p->next;
while(p->next!=NULL){cout<<q->data<<" ";p=q;q=q->next;}
cout<<endl;
}
void Delete_LinkList(LNode *L,int i)
/* 删除以L为头结点的单链表中的第i个结点 */
{ int j=0; LNode *p,*q;
p=L; q=L->next;
while ( p->next!=NULL&& j<i-1)
{ p=q; q=q->next; j++; }
if (!p->next || j>i-1) cout<<"i太大或i为0!!\n ";
/*长度为n的链表的合法删除位置是1到n*/
else
{ p->next=q->next; free(q); }
}
void G(LNode *L,int i)
{
int j=1;
LNode *p,*q;p= (LNode *)malloc(sizeof(LNode));q= (LNode *)malloc(sizeof(LNode));p=L;q=p->next;
while(p->next!=NULL)
{
if(j%i==0){cout<<" "<<q->data<<" ";p=q;q=q->next;j++;/*Delete_LinkList(L,j);*/cout<<"dstfhj";}
else {p=q;q=q->next;j++;}
}
}
void main()
{ int m;Lnode s;Lnode L; L=*create_LinkList();X(&L);cout<<"asds请输入第几个囚犯会被处决: ";
cin>>m; cout<<"被处决囚犯序号: ";G(&L,m);//Delete_LinkList(&L,m);s.data=et_Elemcout<<s.data;
}
约瑟夫问题:
n个人排成一圈。从某个人开始,按顺时针方向依次编号。从编号为1的人开始顺时针“一二一”报数,报到2的人退出圈子。这样不断循环下去,圈子里的人将不断减少。由于人的个数是有限的,因此最终会剩下一个人。试问最后剩下的人最开始的编号。
输入格式 Input Format
一个正整数n,表示人的个数。输入数据保证数字n不超过100位。
输出格式 Output Format
一个正整数。它表示经过“一二一”报数后最后剩下的人的编号。
样例输入 Sample Input
9
样例输出 Sample Output
3
时间限制 Time Limitation
各个测试点1s
注释 Hint
样例说明
当n=9时,退出圈子的人的编号依次为:
2 4 6 8 1 5 9 7
最后剩下的人编号为3
初见这道题,可能会想到模拟。可是数据实在太大啦!!
我们先拿手来算,可知n分别为1,2,3,4,5,6,7,8...时的结果是1,1,3,1,3,5,7,1...
有如下规律:从1到下一个1为一组,每一组中都是从1开始递增的奇数,且每组元素的个数分别为1,2,4...
这样就好弄了!!