入队
通过push()方法在队尾插入一个新的元素。
#include <queue>
using namespace std;
int main(){
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
return 0;
}
获取队首元素
通过front()方法可以获取到当前的队首元素。
#include <queue>
#include <iostream>
using namespace std;
int main(){
queue<int> q;
q.push(1);
cout<<q.front()<<endl;
q.push(2);
cout<<q.front()<<endl;
q.push(3);
cout<<q.front()<<endl;
return 0;
}
出队
通过pop()方法可以让队首元素出队。
#include <queue>
#include <iostream>
using namespace std;
int main(){
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.pop();
cout<<q.front()<<endl;
q.pop();
cout<<q.front()<<endl;
q.pop();
return 0;
}
判断队列是否为空
empty()方法可以判读队列是否为空,如果为空,方法返回true,否则返回false。这个方法的意义是,在我们每次调用front()和pop()之前,都要检查一下,保证队列不为空,否则去访问一个空队列的首部或者让一个空队列出队就会发生错误。
#include <queue>
#include <iostream>
using namespace std;
int main(){
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
while(!q.empty()){//如果队列不空,一直出队,用这样的方法清空一个队列,因为队列没有clear方法
cout<<q.front()<<endl;
q.pop();
}
return 0;
}
清空
队列比较特殊,并没有clear()方法,而清空一个队列,需要手动清空。
while(!q.empty()){//如果队列不空,一直出队,用这样的方法清空一个队列,因为队列没有clear方法
cout<<q.front()<<endl;
q.pop();
}
#include <queue>
#include <iostream>
#include <string>
using namespace std;
int main(){
queue<string> q;
q.push("zhangsan");
q.push("lisi");
q.push("wangwu");
while(!q.empty()){
cout<<q.front()<<endl;
q.pop();
}
return 0;
}
演算发现结果是6,
#include <queue>
#include <iostream>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
queue<int> q;
for(int i=1;i<=n;i++){
q.push(i);
}
int cur=1;
while(q.size()>1){
int x=q.front();
q.pop();
if(cur==m){
cur=1;
}else{
q.push(x);
cur++;
}
}
cout<<q.front()<<endl;
return 0;
}
广度优先搜索
void bfs(起始点){
将起始点放入队列中;
标记起始点访问;
while(如果队列不为空){
访问队列中队首元素x;
删除队首元素;
for(x所有相邻点){
if(该点未被访问过且合法){
将该点加入队列末尾;
}
}
}
队列为空,广搜结束;
}
#include <iostream>
#include <string>
#include <queue>
using namespace std;
int n,m;
string maze[110];
bool vis[110][110];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
bool in(int x,int y){
return 0<=x && x<=n && 0<=y && y<=m;
}
struct node{
int x,y,d;
node(int xx,int yy,int dd){
x=xx;
y=yy;
d=dd;
}/*在结构体中定义一个构造函数,当创建一个 node 类型的对象时,可以通过传入参数来调用构造函数,从而初始化对象的 x, y, d 成员变量。*/
};
int bfs(int sx,int sy){
queue<node> q;
q.push(node(sx,sy,0));
vis[sx][sy]=true;
while(!q.empty()){
node now =q.front();
q.pop();
for(int i=0;i<4;i++){
int tx=now.x+dir[i][0];
int ty=now.y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
if(maze[tx][ty]=='T'){
return now.d+1;
}else{
vis[tx][ty]=true;/*虽然在判断条件中有 !vis[tx][ty] 这个条件,但在实际处理中,可能会存在多个路径经过相同的位置,所以需要确保每个位置只被访问一次,避免重复访问或者形成死循环。因此,即使在 if 语句块中已经判断了 !vis[tx][ty],为了确保正确性和完整性,还是会在访问该位置后将其标记为已访问 vis[tx][ty] = true;。这样可以避免程序出现错误或进入死循环,确保算法能够正确地搜索到最短路径。*/
q.push(node(tx,ty,now.d+1));
}
}
}
}
return -1;//没有找到路径
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>maze[i];
}
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i,y=j;
}
}
}
cout<<bfs(x,y)<<endl;
return 0;
}
#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
queue<pair<int,int> > q; // 定义一个队列用于存储待访问的节点坐标以及步数
bool vis[5005]; // 定义一个数组用于标记节点是否被访问过
int main(){
int n, A, B, now, step;
scanf("%d%d%d", &n, &A, &B); // 输入总长度 n,起点 A,终点 B
q.push(make_pair(A, 0)); // 将起点 A 和步数 0 入队
vis[A] = true; // 标记起点 A 已被访问
while(!q.empty()){
now = q.front().first; // 获取当前节点
step = q.front().second; // 获取到达当前节点的步数
q.pop(); // 出队当前节点
if(now == B){ // 如果当前节点为终点 B,输出步数并结束循环
printf("%d\n", step);
break;
}
// 分别尝试向前、向后、向倍增的方向移动一步,并将新节点入队
if(now + 1 <= n && !vis[now + 1]){
q.push(make_pair(now + 1, step + 1));
vis[now + 1] = true;
}
if(now - 1 >= 0 && !vis[now - 1]){
q.push(make_pair(now - 1, step + 1));
vis[now - 1] = true;
}
if(now * 2 <= n && !vis[now * 2]){
q.push(make_pair(now * 2, step + 1));
vis[now * 2] = true;
}
}
return 0;
}
pair
是 C++ STL(标准模板库)中的一个模板类,用于表示一对值。它可以存储两个值,这两个值的类型可以不同。例如,pair<int, string>
可以存储一个整数和一个字符串。make_pair
是一个函数模板,用于创建一个pair
对象并初始化其值。在使用
pair
时,可以使用first
和second
成员变量来访问其中的第一个值和第二个值。例如:pair<int, string> p = make_pair(10, "hello"); cout << p.first << " " << p.second << endl; // 输出:10 hello