約瑟夫問題的變種。
約瑟夫問題對我而言,有着特別的意義。我高一遇到的第一道難題就是約瑟夫問題;大一喜歡的女生問我的第一道問題也是約瑟夫問題(目前仍然爲情所困,不知前途何方);鏈表的第一個實現也是約瑟夫問題。
這道題,就是有兩個取孩子的操作。當然可以用鏈表做,但是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;
}