分数 100
全屏浏览题目
切换布局
作者 程序设计课题组
单位 福州大学
某部队进行新兵队列训练,将新兵从1开始按顺序依次编号,并排成一行横队。训练的规则如下:从头开始1至2报数,凡报到2的新兵出列,剩下的新兵向小序号方向靠拢;再从头开始进行1至3报数,凡报到3的新兵出列,剩下的向小序号方向靠拢;继续从头开始进行1至2报数。。。;如此这样一直进行,直到剩下的人数不超过3人为止。
输入格式:
第一行输入一个整数T(0<T<100),表示共有T组新兵进行训练;
接下来有T行,每行输入一个整数N(0<N<=5000),代表这组新兵的人数。
输出格式:
输出共T行,每行按照编号从小到大的顺序输出每组新兵进行训练后剩下的新兵编号,编号之间以空格分隔,每行末尾有一个换行符。
输入样例:
2
20
40
输出样例:
1 7 19
1 19 37
代码长度限制
16 KB
时间限制
1000 ms
内存限制
64 MB
#include<stdio.h>
#include<stdlib.h>
typedef struct queue queue;
struct queue{
int rank;
queue *prior;
queue *next;
int size;
};
void print(queue *queue1){
queue *p = queue1->next;
while(p!=NULL){
if(p->next!=NULL)printf("%d ", p->rank);
else
printf("%d\n", p->rank);
p = p->next;
}
}
queue *delete_LB(queue *queue1){
queue *k = queue1;
queue1->prior->next = queue1->next;
if(queue1->next!=NULL)queue1->next->prior = queue1->prior;
queue1 = queue1->prior;
free(k);
return queue1;
}
queue *create(int n){
queue *head;
queue *p, *q;
head = (queue*)malloc(sizeof(queue));
head->prior = NULL;
head->next = NULL;
for (int i = 1; i <= n;i++){
q = (queue *)malloc(sizeof(queue));
q->rank = i;
if(i==1){
head->next = q;
q->prior = head;
q->next = NULL;
}else {
p->next = q;
q->prior = p;
q->next = NULL;
}
p = q;
}
return head;
}
int main(){
int n;
scanf("%d", &n);
queue document[105];
queue *a;
for (int i = 1; i <= n;i++){
int count;
scanf("%d", &count);
a = create(count);
a->size = count;
queue *p;
while(a->size>3){
p = a->next;
for (int j = 1; j <= count; j++)
{
if (j % 2 == 0)//这里无需判断是否size>3,因为无论是否满足,都必须在进行的一轮内将所有2的报数删除;
{
p=delete_LB(p);
a->size--;
}
p = p->next;
}
count = a->size;
p = a->next;
if(a->size>3)//这里加上size>3的判断才能保证n=40的情况下37不会被删除,否则还会进行一次j=3时的删除操作;特殊情况(即处理完上一轮2的报数后size恰好为3,但是此时没有加入判断的话循环会继续运行,会多删除1项)
{
for (int j = 1; j <= count; j++)
{
if (j % 3 == 0)
{
p = delete_LB(p);
a->size--;
}
p = p->next;
}
}
count = a->size;
}
document[i] = *a;
}
for (int i = 1; i <= n;i++){
print(&document[i]);
}
return 0;
}