hdu,1276,士兵队列训练问题

本文介绍了一种通过交替使用一至二报数和一至三报数来筛选士兵的算法。该算法应用于新兵队列训练中,直至剩下不多于三名士兵。文章提供了具体的实现代码,并展示了如何通过循环队列进行人员的筛选。

士兵队列训练问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2673    Accepted Submission(s): 1220

Problem Description

某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。

 

 

Input

本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000

 

 

Output

共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。

 

 

Sample Input

2

20

40

 

 

Sample Output

1 7 19

1 19 37

 

 

Author

Cai Minglun

 

 

Source

杭电ACM集训队训练赛(VI

 

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
typedef struct str
{
    int cap;
    int size;
    int h;
    int t;
    int *arr;
}que;
void stque(que *q,int n)
{
    q->cap=n;
    q->h=0;
    q->t=0;
    q->size=0;
    q->arr=(int *)malloc(sizeof(int)*n);
}
int inque(que *q,int x)
{
    q->size++;
    q->arr[q->t]=x;
    q->t=(q->t+1)%q->cap;
    return 0;
}
int outque(que *q)
{
    int t;
    q->size--;
    t=q->arr[q->h];
    q->arr[q->h]=0;
    q->h=(q->h+1)%q->cap;
    return t;
}
void freeque(que *q)
{
    free(q);
}
int main()
{
    int cases,x,i,tem;
    que *q1=NULL,*q2=NULL,*ans=NULL;
    scanf("%d",&cases);
    while (cases--)
    {
        q1=(que *)malloc(sizeof(que));
        q2=(que *)malloc(sizeof(que));
        scanf("%d",&x);
        stque(q1,x+5);
        for (i=1;i<=x;i++)
            inque(q1,i);
        ans=q1;
        while (q1->size>3)
        {
            stque(q2,x+5);
            while (q1->h!=q1->t)
            {
                tem=outque(q1);
                if ((q1->h)%2!=0)//如果循环队列起作用,这里可能会出错
                    inque(q2,tem);
            }
            if (q2->size<=3)
            {
                ans=q2;
                break;
            }
            stque(q1,x+5);
            while (q2->h!=q2->t)
            {
                tem=outque(q2);
                if ((q2->h)%3!=0)//如果循环队列起作用,这里可能会出错
                    inque(q1,tem);
            }
            if (q1->size<=3)
            {
                ans=q1;
                break;
            }
        }
        for (i=ans->h;i<ans->t-1;i++)
            printf("%d ",ans->arr[i]);
        printf("%d\n",ans->arr[i]);
    }
    return 0;
}


按几天讲的队列的方法自己写了这道题提交时一次过了,但是提交之前调试了很长时间

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值