栈_士兵队列训练问题(循环链表or队列)_注意题意呀
士兵队列训练问题(循环链表or队列)
TimeLimit:1000MS MemoryLimit:32768KB
64-bit integer IO format:%I64d
Problem Description
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。
Input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。
Output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
SampleInput
2 20 40
SampleOutput
1 7 19 1 19 37
// 注意点为 是每轮删去数后才算 N 值是否小于 3. 即是以 2 为跳数, 删去数列时, 就是只剩下 3 个数时也要删。
代码:
#include <cstdio> using namespace std; typedef struct node Node; const int all = 3; struct node { int x; Node *next; }; int make( Node head, int n ); Node* New( int n ); int main(void) { int t, num; Node Head, *tmp; scanf( "%d", &t ); while( t -- ){ scanf( "%d", &num ); Head.next = New( num ); num = make( Head, num ); while( num -- ){ printf( "%d", Head.next->x ); tmp = Head.next->next; delete Head.next; Head.next = tmp; if( num ){ putchar( ' ' ); } } putchar( '\n' ); } return 0; } Node* New( int n ) { Node head, *tmp;; head.next = NULL; if( n ){ head.next = tmp = new Node; tmp->x = 1; tmp->next = NULL; for( int i=2; i <= n; ++ i ){ tmp->next = new Node; tmp = tmp->next; tmp->x = i; tmp->next = NULL; } } return head.next; } int make( Node head, int n ) { Node *tmp, *tmp2; while( n > all ){ tmp = head.next; while( tmp ){ if( tmp && tmp->next ){ tmp2 = tmp->next->next; delete tmp->next; tmp->next = tmp2; tmp = tmp2; -- n; } else break; } tmp = head.next; while( n > 3 ){ if( tmp && tmp->next && tmp->next->next ){ tmp2 = tmp->next->next->next; delete tmp->next->next; tmp->next->next = tmp2; tmp = tmp2; -- n; } else break; } } return n; }