zoukankan      html  css  js  c++  java
  • HDU1276士兵队列训练问题 循环队列

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

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

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

    Sample Input
    2
    20
    40

    Sample Output
    1 7 19
    1 19 37

    Author
    Cai Minglun
    **

    思路
    类似于约瑟夫环 用两个队列模拟一下报数方式 一个队列存出队前的原始士兵顺序 另一个队列存出队后的士兵顺序 当人数小于4时,输出士兵顺序

    #include<stdio.h>
    #include<algorithm>
    #include<algorithm>
    using namespace std;
    #define N 5002
     struct Q{
        int f,r,da[N];
        void init()
        {
            f=r=0;//队列的初始化 
        }
        int push(int a)
        {
            da[r++] = a;//入队 
        }
        int gettop()
        {
            return da[f++];//取队头元素 
        }
        bool Judge()
        {
            return r-f>=4;
        }
        int empty()
        {
            return f == r;//判断队列是否为空 
        }
    
    }q[2];
    
    
    int main()
    {
        int t,i,first,next,n;
        scanf("%d",&t);
        while( t --)
        {
            scanf("%d",&n);
            first = 0;
            next = 1;
            q[0].init();
            q[1].init();
            for( i = 1; i <= n; i ++)
                q[first].push(i);
            i = 0;
            while(q[first].Judge())
            {
                q[next].init();
                /*报数由1-3时*/  
                if( i&1)
                {
                    while(!q[first].empty())
                    {
                        q[next].push(q[first].gettop());
                        if(q[first].empty())
                            break;
                        q[next].push(q[first].gettop());
                        if(q[first].empty())
                            break;
                        q[first].gettop();
                    }
                }
                else
                {
                    while(!q[first].empty())
                    {
                        q[next].push(q[first].gettop());
                        if(q[first].empty())
                            break;
                        q[first].gettop();
                    }
                }
                swap(first,next);
                i += 1;//由i控制报数的方式 
            }
            printf("%d",q[first].gettop());
            while(!q[first].empty())
                printf(" %d",q[first].gettop());
            printf("
    ");
        }
        return 0;
    }

    后记:这道题get了循环队列这个新技能

  • 相关阅读:
    洛谷P3313&BZOJ-3531【SDOI2014】旅行--线段树动态开点+树链剖分
    BZOJ3932【CQOI2015】任务查询系统&洛谷P3168--主席树区间前K小+差分
    博客中的代码CE说明
    栗栗的书架--洛谷P2468【SDOI2010】&BZOJ 1926二分+前缀和+主席树
    hdu1010--Tempter of the Bone(迷宫)
    hdu1242 Rescue DFS(路径探索题)
    hdu 1241--入门DFS
    注意引用的用法
    划分树---hdu4417---区间查找(不)大于h的个数
    程序员能力矩阵
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7350152.html
Copyright © 2011-2022 走看看