士兵队列训练问题/队列/C语言表达

士兵队列训练问题

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

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

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

Sample Input

2
20
40

Sample Output

1 7 19
1 19 37

思路:

运用队列的思想,想象士兵站成一个圈。就像约瑟夫环。同样的思想。

AC代码:

#include<stdio.h>
#include<string.h>
int main()
{
    int t,n,i;
    while(~scanf("%d",&t))  //多组输入
    {
        while(t--)          //t组输入
        {
            int x=0;        //计数器用来记是否为最后一个,如过时换行,不是就打一个空格(格式要求)
            int k=1;        //用来判断是叫到2的人出列还是3出列,我定义的是k=1时喊二出列,-1时喊三出列
            int a[5050]={0};   //定义一个数组存士兵出列情况,判断是否出列,将出列的赋值为1,没出列的赋值为0
            scanf("%d",&n);
            int cnt=n;         //士兵人数
            //前三中有点特殊需要单独判断,直接判断输出即可,剩下的再进行判断
            if(n==1)
            {
                printf("1\n");continue;
            }
            else if(n==2)
            {
                printf("1 2\n");continue;
            }
            else if(n==3)
            {
                printf("1 2 3\n");continue;
            }
            else{
                while(1)    //定义一个死循环,后面写一个跳出循环的条件就,人数小与等于3
                {
                    x=0;
                    for(i=1;i<=n;i++)
                    {
                        if(k==1)    //喊2的时候
                        {
                            if(a[i]==0)
                            {
                                x++;
                            }
                            if(x==2)
                            {
                                a[i]=1; //出列士兵记录
                                cnt--;  //士兵人数减一
                                x=0;
                            }
                        }
                        if(k==-1)   //喊3的时候
                        {
                            if(a[i]==0)
                            {
                                x++;
                            }
                            if(x==3)
                            {
                                a[i]=1; //出列士兵记录
                                cnt--;  //士兵人数减一
                                x=0;
                            }
                        }

                    }
                    k=-k;   //题目中说一轮3一轮2,在这是交换
                    if(cnt<=3)  //人数小于等于3时跳出循环
                    {
                        break;
                    }
                }
            }
            x=0;
            for(i=1;i<=n;i++)
            {
                if(a[i]!=1)
                {
                    if(x!=0)       // !0时输出空格
                    printf(" ");
                    printf("%d",i);
                    x++;            
                }
            }
            printf("\n");
        }
    }
    return 0;
}
发布了33 篇原创文章 · 获赞 35 · 访问量 1294

猜你喜欢

转载自blog.csdn.net/qq_45856289/article/details/103112904
今日推荐