OpenJudge 2746(三种方法解决Joseph问题)
#include<stdio.h>
#include<string.h>
int vis[310];
void joseph(int n,int m)
{
int i,j,k;
int cnt=0,count=0;
memset(vis,0,sizeof(vis));//0表示未选中
for(i=1;count<n-1;i=i%n+1)//循环 n-1次
{
if(vis[i]==0)
{
// vis[i]=1;
cnt++;
}
if(m==cnt)
{
vis[i]=1;//出圈
cnt=0;
count++;
}
}
for(j=1;j<=n;j++)
if(vis[j]==0)
{
printf("%d\n",j);
break;
}
}
int main()
/*
[Linker error] undefined reference to `WinMain@16' ,便是把main 写成了mian
*/
{
int m,n;
while(scanf("%d%d",&n,&m),n||m)
joseph(n,m);
return 0;
}
/*
下面写递推公式:令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]
递推公式 f[1]=0; f[i]=(f[i-1]+m)%i; (i>1)
因为实际生活中编号总是从1开始,我们输出f[n]+1 由于是逐级递推,不需要保存每个f[i]
*/
#include <stdio.h>
#include<stdlib.h>
int main()
{
int n,m,i,s=0;
scanf("%d%d",&n,&m);
for(i=2; i<=n; i++)
s=(s+m)%i;
printf("The winner is %d\n", s+1);
system("pause");
}
//尾插法带头结点的单向链表
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct Node
{
int num;
struct Node *next;
}Node;
int main()
{
int i,j,n,m,count;
Node *head,*p,*q;
head=p=(Node *)malloc(sizeof(Node));
while(scanf("%d%d",&n,&m),n||m)
{
for(i=1;i<=n;i++)
{
q=(Node *)malloc(sizeof(Node));
q->num=i;
p->next=q;
p=p->next;
}
p->next=head;//构成循环链表 ,此时pq是一样的
j=0,count=0;
for(p=head,q=p->next;count<n-1;)
{
j++;
if(j==m)//删除 q结点
{
p->next=q->next;
free(q);
q=p->next;//因为此时q已经释放,不能写成 q=q->next
count++;//不能写在for内
j=0;
}
else
{
p=p->next;
q=p->next;
}
if(q==head)//数到头结点则跳过去
{
p=p->next;
q=q->next;
}
/*
if(count==n-1) break;
这句也可,不要for内的条件判定,但是不可放在第一个if内 ;
因为需要经过第二个if
*/
}
printf("%d\n",q->num);//或者p->next->num,因为最后就剩两个节点,且p=head,q=head->next
}
return 0;
}
/*
若是多次输入,第一次结果正确,再次输入相同内容,结果不对
很可能是因为某些语句位置不正确,特别是带break的,(比如
printf语句中的变量在break语句之后还会有变化)
*/
作者:火星十一郎
本文版权归作者火星十一郎所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

浙公网安备 33010602011771号