題目:
Description
n個人圍成一圈,依次從1至n編號。從編號為1的人開始1至k報數,凡報數為k的人退出圈子,輸出最後留下的一個人原來的編號。
Input
首先輸入一個t,表示有t組資料(1<= t <= 10010)
然後有t行,每行有2個正整數n和k。(1<= n,k<= 20)
Output
對於每組測試資料,輸出一個數,表示最後留下來的人的編號。
樣例:
Sample Input
3
10 3
7 1
5 4
Sample Output
4
7
1
提示: 例如第三組樣例:5個人圍成一圈,編號1-5。第一輪報數4號出列,第二輪從5開始報數1,3報4,3出列,第三輪從5開始報1,5報4,5出列,第四輪1開始報1,2報4,2出列,最後剩下的為1號。
思路:這題是一個約瑟夫問題,處理方式就是用一個陣列,其下標表示序號,其存的指用0,1分別表示其是否出去了,然後用迴圈,依次進行,若沒出去則看這個是第幾個沒出去的,若是要出去的報數的那個數的倍數,則讓其出去,即將存的指由1變為0;然後再找一個計數器表示剩餘人數,當剩餘只有1個的時候則跳出迴圈,輸出最後的;
新技巧:在於用陣列的下標表示序號,用內部存的值表示其狀態,還有一個重要的點就是人數計數器,因為這裡是要記錄出去的人數,所以一開始計數器為總數,之後每次出去就減一,這樣從邏輯上好記錄與理解;
程式碼:
#include<stdio.h>
#include<string.h>
int main()
{
int i,t,x,y,a[10015];
scanf("%d",&t);
for(i=0;i<t;i++)
{
memset(a,0,sizeof(a));
scanf("%d%d",&x,&y);
int num=x,j,k;
for(j=1;j<=x;j++)
a[j]=1;
k=0;
for(j=0;;j++)
{
if(a[j%x+1])
{
k++;
if(k%y==0)
{
if(num==1)
break;
a[j%x+1]=0;
num--;
}
}
}
printf("%d
",j%x+1);
}
return 0;
}