看到这个题,跟约瑟夫环感觉差不多,但是这个数据范围比较小,可以模拟实现,我用的是循环链表实现的过程。中间用到了标记,因为对于样例10 4 3来说,就会到后边只剩下7 10这两个节点形成的环,但是now_n这时候指向已删除的2节点,now_f指向已删除的6节点,然而,这就需要让now_n继续向后指,也指向6节点,这样就需要标记是否还在环内。
#include<stdio.h>
#include<iostream>
using namespace std;
struct node {
int a;
bool flg; //mark the node is the part of the ring or not
node *next;
node *fron;
};
node *head, *endd;
void bui_cir_link ( int nn ) { //form a ring with two-way linked list
node *tmp, *temp;
head = new ( node );
head->a = 1;
head->flg = 1;
head->fron = NULL;
head->next = NULL;
tmp = head;
for ( int i = 2; i <= nn; i++ )
{
temp = new node;
tmp->next = temp;
temp->fron = tmp;
temp->a = i;
temp->flg = 1;
tmp = temp;
}
endd = tmp;
endd->next = head;
head->fron = endd;
}
void operate ( int nn, int kk, int mm ) {
int n = nn, num = 0;
node *now_f, *now_n;
now_n = head;
now_f = endd;
while ( nn-- ) {
if ( nn != n - 1 ) //specially operate the star
now_n = now_n->next;
for ( int i = 1; i < kk; i++ ) {
now_n = now_n->next;
}
if ( nn != n - 1 )
now_f = now_f->fron;
for ( int i = 1; i < mm; i++ ) {
now_f = now_f->fron;
}
now_n->next->fron = now_n->fron; //delete
now_n->fron->next = now_n->next;
num++; //records the number of deleted node
now_n->flg = 0; //mark
printf("%3d",now_n->a);
if ( num == n ) {
break;
}
if ( now_n != now_f ) {
now_f->fron->next = now_f->next;
now_f->next->fron = now_f->fron;
num++;
now_f->flg = 0;
printf("%3d",now_f->a);
if ( num == n ) {
break;
}
}
// else
// now_f= now_n; //delete the same node
for ( int i = 0;; i++ ) { //finding the closest deleted node with ring
if ( !now_n->next->flg ) {
now_n = now_n->next;
}
else
break;
}
for ( int i = 0;; i++ ) {
if ( !now_f->fron->flg ) {
now_f = now_f->fron;
}
else
break;
}
cout << ",";
}
}
int main() {
int n, m, k;
while ( scanf ( "%d%d%d", &n, &k, &m ) != EOF && n && m && k ) {
bui_cir_link ( n );
operate ( n, k, m );
cout << endl;
}
return 0;
}