约瑟夫问题的变种。
约瑟夫问题对我而言,有着特别的意义。我高一遇到的第一道难题就是约瑟夫问题;大一喜欢的女生问我的第一道问题也是约瑟夫问题(目前仍然为情所困,不知前途何方);链表的第一个实现也是约瑟夫问题。
这道题,就是有两个取孩子的操作。当然可以用链表做,但是lrj用的是数组模拟的方法,把取过的元素设置为0.这个方法很好,所以我也写了一个。
然后出现了这么几个bug:
1.题目意思一开始没看清楚,以为每次都是从1和n取,写错了一发,还好样例数据测出错误了。这说明再简单的水题,都要先拿样例数据测试一下,再去写。
2.逗号一开始写错了
3.数组设置为0后还有一些小问题,我也解决了。主要是go函数起始点的问题。
不得不说,这个go函数设计的非常巧妙,学习一个!
#include<bits/stdc++.h>
using namespace std;
int tt=0,n,k,m,ans1,ans2,leftt;//left代表目前还有几个元素(1-left)
int a[25];
int go(int start,int d,int step)//从start走step步,方向为d,逆时针为正,顺时针为负
{
int xx=start-d;
while(step)
{
//printf("xx=%d step=%d\n",xx,step);
xx=xx+d;
if(xx==n+1)
xx=1;
if(xx==0)
xx=n;
if(a[xx]==0)
continue;
else
step--;
}
return a[xx];
}
int main(void)
{
while(scanf("%d%d%d",&n,&k,&m))
{
if((n==0)&&(k==0)&&(m==0))
break;
for(int i=1;i<=n;i++)
a[i]=i;
leftt=n;
//printf("Stop 1\n");
tt=0;
ans1=1;
ans2=n;
while(leftt)
{
if(tt==0)
tt++;
else
printf(",");
ans1=go(ans1,1,k);
ans2=go(ans2,-1,m);
a[ans1]=a[ans2]=0;
if(ans1==ans2)
{
leftt-=1;
printf("%3d",ans1);
}
else
{
leftt-=2;
printf("%3d%3d",ans1,ans2);
}
}
printf("\n");
}
return 0;
}
版权声明:本文为fanesemyk原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。