這題用雙向循環鏈表的時間是O(NK),明顯是過不了的,但是爲了練練手,還是寫了一下
#include <cstdio>
#include <algorithm>
using namespace std;
struct List
{
List* pre;
int value;
List* next;
};
int main(){
int i,j;
int n,k,m;
while(scanf("%d %d %d",&n,&k,&m)){
List *list=new List;
if(k==0 && m==0 && n==0)
break;
list->value=1;
list->next=list;
list->pre=list;
List *start=list;
for(i=2;i<=n;i++){
List *a=new List;
a->value=i;
a->pre=list->pre;
a->next=list;
list->pre->next= a;
list->pre=a;
if(i==m)
start=a;
}
if(n>1){
start->pre->next=start->next;
start->next->pre=start->pre;
List *t=start->next;
printf("%d\n",start->value);
delete start;
start=t;
}
else{
printf("%d\n",start->value);
continue;
}
int s=n-1;
while(s>1){
if(s==2){
printf("%d %d\n",start->value,start->next->value);
}
int temp=k-1;
while(temp--){
start=start->next;
}
start->pre->next=start->next;
start->next->pre=start->pre;
List *t=start->next;
printf("%d\n",start->value);
delete start;
start=t;
s--;
}
printf("%d\n",start->value);
}
return 0;
}
然後用遞推的方式又寫了一個,把第一個M去掉,並且把所有的編號減去一個M,在最後再加回去
#include <cstdio>
#include <algorithm>
using namespace std;
int main(){
int i,j;
int n,k,m;
while(scanf("%d %d %d",&n,&k,&m)!=EOF){
if(n==0)
break;
int a[2];
a[0]=0;
int v=0;
for(i=2;i<=n-1;i++){
v=1-v;
a[v]=(a[1-v]+k)%i;
}
printf("%d\n",(a[v]+m)%n+1);
}
}