队列
基本概念![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2cda4a6135cc27d616463f10b27fe721.png)
形式上为先进先出
下面是具体题目的应用
林大oj 1634
此题十分简单,应用的就是队列先进先出的性质,形成闭环,一直绕出答案
代码实现如下
#include <bits/stdc++.h>
using namespace std;
queue<int>p;
int n,m,s1,s2;
int main()
{
cin>>n>>m;
for(int i=1; i<=n; i++)
{
p.push(i);
}
while(!p.empty())
{
for(int i=0; i<m; i++)
{
if(i!=m-1)
{
s1=p.front();
p.pop();
p.push(s1);
}//循环前m次都是将队列的第一个取出放至最末位置
else
{
s2=p.front();
p.pop();//若是报道m的,则删去
if(p.empty())//判断是否空,空则输出已存下的s2
cout<<s2<<endl;
}
}
}
return 0;
}
第二题
林大oj 1633 取牌游戏-队列-SET
代码实现如下
#include <bits/stdc++.h>
using namespace std;
queue<int>p;
int a[100001],N,K,P,n1,s1,s2,n2;
int main()
{ cin>>N>>K>>P;
for(int i=1;i<=K;i++)
{
p.push(i);
}
while(!p.empty())//表示纸牌还有剩余时
{
s1=p.front();
p.pop();//发一张牌
for(int i=0;i<P;i++)//移动牌
{
s2=p.front();
p.pop();
p.push(s2);
}
n2++;
if(n2%N==0) a[n1++]=s1;//若为N的倍数,即为给小明的牌,存进数组
}
sort(a,a+K/N);//进行排序输出
for(int i=0;i<K/N;i++)
{ if(i!=K/N-1)
cout<<a[i]<<endl;
else
cout<<a[i];
}
return 0;
}
第三题
林大oj 1635
本题用到结构体与队列配合使用,重在读题哈哈哈,逻辑倒是不难,下面是代码实现
#include <bits/stdc++.h>
using namespace std;
int n,m,t,n1;
struct stu
{
int num;
string name;
} p[10001];//结构体
queue<stu>vis;//定义结构体类型的队列
bool judge(int a)//判断函数
{
if(a%7==0)
return 1;
while(a)//判断每一位是否为7
{
if(a%10==7)
return 1;
a=a/10;
}
return 0;
}
int main()
{
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++)进行排序,是报数人成为第一个,才能用队列去操作
{
stu tmp=vis.front();
vis.pop();
vis.push(tmp);
}
while(vis.size()>1)//简单的判断
{
if(judge(t)==1)
{
vis.pop();
}
else
{
stu tmp=vis.front();
vis.pop();
vis.push(tmp);
}
t++;
}
printf("%s\n",vis.front().name.c_str());
return 0;
}
第四题
此题比较难
林大oj 1636
代码实现如下
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+1;//定义数组过大时,用此法不会出问题
struct node{
int t;//到达时间
int x;//到达人员国籍
};
queue<node>vis;
int k,x,t,ans,n,num[N];
int main()
{
cin>>n;
while(n--)//每队每队的进行
{
cin>>t>>k;
for(int i=0;i<k;i++)
{
cin>>x;
vis.push({t,x});//队列中的结构体输入
if(num[x]==0) ans++;//第一次出现此国籍,答案数加一
num[x]++;
}
while(t-vis.front().t>=86400&&!vis.empty())//若下一艘到达的时间差超过24小时,需要踢掉超时的人,且因为后来的定会超时,所以踢掉无影响
{
node tmp=vis.front();
vis.pop();
int a=tmp.x;
num[a]--;//国籍人数相应减少
if(num[a]==0) ans--;//若减少至0,则答案数减1
}
cout<<ans<<endl;
}
return 0;
}
第五题
林大oj 1663 关系网络
代码实现如下
#include <bits/stdc++.h>
using namespace std;
int a[101][101],n,x,y,p[101],i,j;
int main()
{
cin>>n>>x>>y;
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)
p[j]++;
for( j=1; j<=n; j++)
if(p[j]!=0)
for( int m=1; m<=n; m++)
if(a[j][m]!=0)
a[x][m]=1;
if(a[x][y]!=0)
{
break;
}
}
else i=0;
cout<<i<<endl;
}
第六题
林大oj 1662 Blash数集-队列-set
此题不用队列,类似于之前的丑数
找到排序规律是关键
丑数
代码实现如下
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+20;
int a[N],p1=1,p2=1,t1,t2,n,a1;
int main()
{
cin>>a[1]>>n;
for(int i=2;i<=n;i++)//从第二位开始,一位一位的排,题目给的两种算法,进行选择,这样才能确保从小到大依次排序
{
a[i]=min(a[p1]*2+1,a[p2]*3+1);//取最小的赋值,并且给最小的增大底数
if(a[i]==a[p1]*2+1) p1++;
if(a[i]==a[p2]*3+1) p2++;
}
cout<<a[n]<<endl;
return 0;
}
第七题
1632 周末舞会-队列
最简单的一道队列题
代码
#include <bits/stdc++.h>
using namespace std;
queue<int>a;
queue<int>b;
int m,n,s1,s2,k;
int main()
{
cin>>m>>n>>k;
for(int i=1;i<=m;i++)
{
a.push(i);
}
for(int i=1;i<=n;i++)
{
b.push(i);
}
for(int i=0;i<k;i++)
{
s1=a.front();
s2=b.front();
if(i!=k-1)
cout<<s1<<" "<<s2<<endl;
else
cout<<s1<<" "<<s2;
a.pop();
b.pop();
a.push(s1);
b.push(s2);
}
return 0;
}