大一寒假集训(8)—队列
知识点
队列的定义 ❤️
队列就是允许在一端进行插入,在另一端进行删 除的线性表。允许插入的一端称为队尾,通常用一个 队尾指针r指向队尾元素,即r总是指向最后被插入的 元素;允许删除的一端称为队首,通常也用一个队首 指针f指向排头元素的前面。初始时f=r=0
队列的基本操作 ❤️
(1)初始化队列 queue < int > vis,定义一个队列
(2)入队 vis.push(x)
(3)出队 vis.pop()
(4)判断队列是否为空 vis.empty()
(5)判断队列中元素的数量vis.size()
(6)得到队列的队首元素 vis.front()
1.周末舞会-队列 nefu 1632
#include <bits/stdc++.h>
using namespace std;
int i;
int a,b;
queue <int> m0;
queue <int> n0;//定义男生和女生的队列
int main()
{
int m,n;//男生和女生
int k;//舞曲数即循环次数
cin>>m>>n;
cin>>k;
for (i=1;i<=m;i++)//以下两个循环输男生和女生入队列
m0.push(i);//将男生的人编号成1 2 3 ...
for (i=1;i<=n;i++)
n0.push(i);
for(i=1;i<=k;i++)
{
a=m0.front();
m0.pop();
b=n0.front();
n0.pop();
printf("%d %d\n",a,b);
n0.push(b);
m0.push(a);
}
return 0;
}
2.取牌游戏-队列-SET nefu 1633
#include<bits/stdc++.h>
using namespace std;
queue <int> poker;//纸牌队列
int i,j;
int n,k,p;//n为游戏人数 p为放低部的牌数 k总牌数
int ch;//判断是否发到小明
int a[100010];//记录小明抽到的牌,后续进行排序
int main()
{
ios::sync_with_stdio(false);
int a1;
ch=0;j=0;//注意初始化
cin>>n>>k>>p;
for (i=1;i<=k;i++)
poker.push(i);//将纸牌编号并放入
while (!poker.empty())
{
ch++;
if (ch%n==0)
{
a[j++]=poker.front();
//j++;
}
poker.pop();
for (i=1;i<=p;i++)
{
a1=poker.front();
poker.push(a1);
poker.pop();
}
}
sort(a,a+j);//排序
for(i=0;i<j;i++)
cout<<a[i]<<endl;
return 0;
}
3.报数-队列-约瑟夫 nefu 1634
本题比第二道简单
#include <bits/stdc++.h>
using namespace std;
queue <int> child;
int n,m;
int i;
int a0,a1;
int main()
{
ios::sync_with_stdio(false);//注意此处,提高效率
cin>>n>>m;
for (i=1;i<=n;i++)
child.push(i);
while (!child.empty())
{
//a1=child.front();
if (child.size()==1)
break;
for (i=1;i<m;i++)
{
a0=child.front();
child.push(a0);
child.pop();
}
child.pop();
}
cout<<child.front();
return 0;
}
4.酒桌游戏-队列 nefu 1635
#include <bits/stdc++.h>
using namespace std;
int n,m,t;
struct aaa
{
int num;
string name;
}a[1005];
queue <int>b;
int judge(int t)
{
int z;
if (t%7==0)
return 1;
while (t)
{
if (t%10==7)
{
return 1;
//break;
}
t=t/10;
}
return 0;
}
int main()
{
int i,j;
int r;
int n,m,t;
cin>>n>>m>>t;
for (i=1;i<=n;i++)
{
cin>>a[i].name;
a[i].num=i;
b.push(i);
}
for (i=1;i<m;i++)
{
b.push(b.front());
b.pop();
}
t-=1;
while (b.size()>1)
{
t++;
r=b.front();
b.pop();
if (judge(t)==0)
b.push(r);
}
cout<<a[b.front()].name;
return 0;
}
5.海港-队列 nefu 1636
#include <bits/stdc++.h>
using namespace std;
const int N=300010;
struct lay
{
int t;
int co;
};
queue<lay> s;
int n,t,k,co,y,ans=0;
int good[N];
int main()
{
struct lay tmp;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>t;
cin>>k;
for(int j=1;j<=k;j++)
{
scanf("%d",&co);
//cin>>x;
s.push({t,co});
if (good[co]==0) ans++;
good[co]++;
}
while(t-s.front().t>=86400)//若两船时间差距大于一天
{
tmp=s.front();
s.pop();
y=tmp.co;
good[y]--;
if (good[y]==0) ans--;
}
cout<<ans<<endl;
}
return 0;
}
6.Blash数集-队列-set nefu 1662
⭐️ 此题与丑数类似
本博客最后一篇为丑数
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int i,j;
int x1,x2;
int main()
{
int a[N],n;
cin>>a[1];
cin>>n;
x1=x2=1;
for (i=2;i<=n;i++)//打表
{
a[i]=min(2*a[x1]+1,3*a[x2]+1);
if (a[i]==2*a[x1]+1) x1++;
if (a[i]==3*a[x2]+1) x2++;
}
cout<<a[n];
return 0;
}
7.关系网络-队列 nefu 1663
⭐️ 注意判断x与y是否一开始便认识
⭐️ 解题思路⭐️先寻找认识x的人z(们),然后寻找认识z(们)的r(们),然后将其对应的a[x][r]变为1。i用于计算次数,一旦a[x][y]为1,循环结束,得到最少的人
#include <bits/stdc++.h>
using namespace std;
//n<=100
int i,j;
int n,x,y;
int a[105][105];
int b[105];
int main()
{
while ( cin>>n>>x>>y)//注意此题为多组输入
{
int b[105]={0};
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
cin>>a[i][j];
if (a[x][y]==0)
for (i=1; i<=n; i++)
{
for (j=1; j<=n; j++)
if (a[x][j]==1)
b[j]++;
for (j=1; j<=n; j++)
{
if (b[j]!=0)
{
for (int r=1; r<=n; r++)
if (a[j][r]==1)
a[x][r]=1;
}
}
if (a[x][y]==1)
break;
}
else i=0;//注意此处的特殊条件
cout<<i<<endl;
}
return 0;
}