大一寒假训练八(队列)

队列

基本概念

在这里插入图片描述
在这里插入图片描述

nefu 1632-周末舞会

在这里插入图片描述在这里插入图片描述思路:由于两个人一一对应,想到用两个队列存储对应输出即可

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int m,f,n;
    queue<int>vis1;//存放男生编号
    queue<int>vis2;//存放女生编号
    cin>>m>>f>>n;//m男生数,f为女生数,n为舞曲数
    for(int i=1;i<=m;i++)
        vis1.push(i);
    for(int i=1;i<=f;i++)
        vis2.push(i);
    for(int i=1;i<=n;i++)
    {
        int s1=vis1.front();//s1存放对首男生
        vis1.pop();//组队之后出去
        int s2=vis2.front();//s1存放对首女生
        vis2.pop();
        printf("%d %d\n",s1,s2);
        vis1.push(s1);//出去之后进入队尾
        vis2.push(s2);
    }
    return 0;
}

nefu 1634 报数-队列-约瑟夫环

在这里插入图片描述
思路:让前d个小朋友不断到队尾,排出第d个小朋友,直到队伍中只有一个小朋友

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N=1e5;
int main()
{
    int n,d,t,ans;//n个小朋友,第d个小朋友离开
    queue<int>vis;//将所有小朋友排好
    cin>>n>>d;
    for(int i=1; i<=n; i++)
        vis.push(i);
    while(vis.size()!=1)//直到只剩下一个小朋友
    {
        for(int i=1;i<=d-1;i++)//让前d个小朋友排到队尾
        {
           ans=vis.front();
           vis.pop();
           vis.push(ans);
        }
        vis.pop();
    }
    printf("%d",vis.front());
    return 0;
}

nefu 1635 酒桌游戏-队列

在这里插入图片描述
思路:
确定开始报数的位置,再判断是否符合条件将其排出或者排到队尾
由于数字和名字是想关联的,需要使用结构体
step1:写一个函数判断其是否符合所需条件
step2:将开始报数的人放到队首
step3:应用上面写的函数判断其是否符合条件,先用node tmp=vis.top()记录队首,再进行判断,符合则直接排出,不符合,放回队尾

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct node{
    int num;
    string name;
}p[10001];
bool judge(int x)//判断此人是否出局
{
    if(x%7==0) return 1;
    while(x)
    {
        if(x%10==7) return 1;
        x=x/10;
    }
    return 0;
}
 queue<node>vis;
int main()
{
    int m,n,t;//t表示开始报数的人报出的数字是t
    //n代表人数,m代表开始报数的人的编号
    string name;
    cin>>n>>m>>t;
    for(int i=1;i<=n;i++)
    {
       cin>>p[i].name;
       p[i].num=i;
    }
    for(int i=1;i<=n;i++)
       vis.push(p[i]);//把队列中的每个数据都输入
    for(int i=1;i<m;i++)//调整顺序,队首的人开始报数
    {
        vis.push(p[i]);
        vis.pop();
    }
    while(vis.size()!=1)
    {
        node tmp=vis.front();
        vis.pop();//把队首拿出去
        if(judge(t)==0) vis.push(tmp);
        //如果对首不符合,再将其放到队尾
        t++;
    }
     printf("%s\n",vis.front().name.c_str());
    return 0;
}

nefu 1663 关系网络-队列

在这里插入图片描述
思路:
从第x行下手,如果a[x][j]=1,a[j][y]=1,那么x能通过关系认识y,此时从j列换为j行,循环每一列,将新认识的人变为1

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int a[101][101],b[101];
//将矩阵存入二维数组
int main()
{
    int n,x,y,i,j,m;
    while(cin>>n>>x>>y)//n维矩阵,x认识y的途径
    {
        for(i=1; i<=n; i++)
            for(j=1; j<=n; j++)
                cin>>a[i][j];
        //正常将矩阵输入
        //当a[x][y]==1时x直接就能认识y了,所以讨论以下情形
        if(a[x][y]==0)
        {
            for(i=1; i<=n; i++) //控制几步
            {
                for(j=1; j<=n; j++) //循环每一列
                {
                    if(a[x][j]==1)
                        b[j]=1;   //如果该行存在1,那么先用数组标记上
                }
                for(j=1; j<=n; j++) //将获取到的列数换位行,可连接传递
                {
                    if(b[j]==1)//如果能取到该列,就能传递到该行
                    {
                        for(m=1; m<=n; m++)//循环新的一行的每列
                        {
                            if(a[j][m]==1)
                                a[x][m]=1;//当第x行能取到y列时,x就能认识y
                        }
                    }
                }
                if(a[x][y]==1)
                    break;
            }
        }
        else i=0;
            printf("%d\n",i);
    }
    return 0;
}

nefu 1636 海港-队列

在这里插入图片描述
在这里插入图片描述
思路:
此题要将结构体按人来定义,因为需要用到每个人的国籍数。判断一个人的国籍是否出现过,使用桶排,a[国籍]==0时,表示其出现一次则让该国籍人数:a[国籍]++,国籍数ans++。当最后一个人比队首入港时间大于24小时时,a[国籍]–;直到a[国籍]==0,此时国籍总数-1

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct human
{
    int time;
    int race;
};
int a[3000000];//记录所有人的国籍,每个人对应数组的一项
queue<human>vis;
int main()
{
    int n,k,t,ans=0,x;//n组数据,t为到达时间,k为人数
    //ans记录总的国籍数,x记录输入时每个人的国籍
    struct human tmp;//tmp用来记录队首
    cin>>n;
    while(n--)
    {
        cin>>t>>k;
        for(int i=1; i<=k; i++)
        {
            cin>>x;
            vis.push({t,x});//把所有人的数据压入队列
            if(a[x]==0)
                ans++;
            a[x]++;
        }//利用桶排,当开始a[x]==0时即多一个国籍数
        while(t-vis.front().time>=86400)//当时间超出24小时
        {//逐渐将最开始的人所在的国籍删除,当记录该国籍的那项变为0,相应总数-1
            tmp=vis.front();
            vis.pop();
            int s1=tmp.race;
            a[s1]--;
            if(a[s1]==0)
                ans--;
        }
        printf("%d\n",ans);
    }
    return 0;
}

nefu 1662 Blash数集-队列-set

在这里插入图片描述
在这里插入图片描述
思路:
与丑数一样,所有的数均由开始的数变化而来,每次取其中最小的即可保证所有的blash数都能取到。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int a[100000+1];
int main()
{
    int p2,n,p3;
    cin>>a[1]>>n;
    p2=1;
    p3=1;
    for(int i=2;i<=n;i++)
    {
        a[i]=min(2*a[p2]+1,3*a[p3]+1);
        if(a[i]==2*a[p2]+1) p2++;
        if(a[i]==3*a[p3]+1) p3++;
    }
    printf("%d",a[n]);
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值