队列的特征是先进先出。
一般用f(first)表示队首,用l(last)表示队尾,然后进行操作
两种方法:
1.STL法:
#include <bits/stdc++.h>
using namespace std;
queue <int> q;
int n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
q.push(i);
while(!q.empty()){
printf("%d ",q.front());
q.pop();
}
return 0;
}
2.数组模拟队列
#include <bits/stdc++.h>
using namespace std;
const int maxn=10000+10;
int q[maxn],n,l,f;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
q[++l]=i;
while(f<l){
f++;
printf("%d ",q[f]);
}
return 0;
}
一些队列的运用:广搜
题意简述:
有一个n*m的迷宫,1为道路,0为墙,2为宝藏,从1,1开始,求出宝藏的坐标和最短的路径,找不到宝藏输出"404 NOT FOUND"。
1.用数组模拟队列
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=100+10;
int q[maxn*maxn][3],p[maxn][maxn],a[maxn][maxn],n,m,f,l;
int d[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
l=1;
q[1][0]=q[1][1]=1;
p[1][1]=1;
while(f<l){
f++;
int x=q[f][0],y=q[f][1];
for(int i=0;i<4;i++){
int xx=x+d[i][0],yy=y+d[i][1];
if(a[xx][yy] && !p[xx][yy]){
q[++l][0]=xx;
q[l][1]=yy;
q[l][2]=q[f][2]+1;
p[xx][yy]=1;
if(a[xx][yy]==2){
printf("%d %d %d",xx,yy,q[l][2]);
return 0;
}
}
}
}
printf("404 NOT FOUND");
return 0;
}
2.STL
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=100+10;
struct node{
int x,y,s;
};
queue <node> q;
int p[maxn][maxn],a[maxn][maxn],n,m;
int d[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
node tmp;
tmp.x=1;
tmp.y=1;
tmp.s=0;
q.push(tmp);
p[1][1]=1;
while(!q.empty()){
tmp=q.front();
for(int i=0;i<4;i++){
int xx=tmp.x+d[i][0],yy=tmp.y+d[i][1];
if(a[xx][yy] && !p[xx][yy]){
node t;
t.x=xx;
t.y=yy;
t.s=tmp.s+1;
q.push(t);
p[xx][yy]=1;
if(a[xx][yy]==2){
printf("%d %d %d",xx,yy,t.s);
return 0;
}
}
}
q.pop();
}
printf("404 NOT FOUND");
return 0;
}
看到这一题
这一题可以用三种方法做:
1.广搜法:
#include <iostream>//坑人的POJ,不能用万能头文件
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=100+5,maxm=10000+10;
int n,m,s,t,ans,a[maxn][maxn],q[maxm][2],d[9][2]={{1,1},{1,0},{1,-1},{0,-1},{0,1},{-1,0},{-1,1},{-1,-1}};//初始化定义坐标数组
char c;//一个字母
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){//输入,如果是"W"就代表有水,设为1,否则就设为0。和上一题一样,这种操作同样潜移默化地将四周设置了一层无形的屏障,如果超过n行m列,就都是0,走无可走。
cin>>c;
a[i][j]=c=='W'?1:0;//三目,也可以如下写:
/*
if(c=='W')
a[i][j]=1;
else
a[i][j]=0;
*/
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]){//如果a[i][j]还没有被灌水,那就灌水吧!!!
ans++;//计数器(存储找到的湖泊总数)
a[i][j]=0;//设为已经走过
q[1][1]=j;//坐标初始化
q[1][0]=i;
s=0;//队列首尾初始化
t=1;
while(s<t){//如果首<尾,BFS
s++;//首加一
for(int k=0;k<8;k++){//向四周的8个方向扩展灌水
int xx=q[s][0]+d[k][0];//存储当前的x坐标和y坐标
int yy=q[s][1]+d[k][1];
if(a[xx][yy]){//如果没有灌过,就继续灌
q[++t][0]=xx;//同样存下新一轮坐标
q[t][1]=yy;
a[xx][yy]=0;//设为已经灌过水了
//和上一题不同的是,这里不需要输出步骤,只需要算出湖泊总数即可,那么也就不需要多定义一个小的单元数组
}
}
}
}
cout<<ans;//输出
return 0;//一个好的程序猿评判标准
}
深搜法
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=100+10;
int a[maxn][maxn];
void find(int x,int y){
a[x][y]=0;
if(a[x+1][y])
find(x+1,y);
if(a[x-1][y])
find(x-1,y);
if(a[x][y+1])
find(x,y+1);
if(a[x][y-1])
find(x,y-1);
if(a[x+1][y-1])
find(x+1,y-1);
if(a[x+1][y+1])
find(x+1,y+1);
if(a[x-1][y+1])
find(x-1,y+1);
if(a[x-1][y-1])
find(x-1,y-1);
}
int main(){
int n,m;
cin>>n>>m;
getchar();
char c;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>c;
a[i][j]=c=='.'?0:1;
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]){
ans++;
find(i,j);
}
cout<<ans;
return 0;
}
这一题
SPFA(不用链式前向星):
#include <bits/stdc++.h>
using namespace std;
const int maxn=10000+105,inf=2147483647;
struct node{
int to,z;
};
int p[maxn],d[maxn],n,m,s,x,y,z,f,l;
vector<node>e[maxn];
int q[maxn*105];
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
node t;
t.to=y;
t.z=z;
e[x].push_back(t);
}
for(int i=1;i<=n;i++)
d[i]=inf;
d[s]=0;
q[1]=s;
p[s]=1;
l=1;
while(f<l){
f++;
int x=q[f];
for(int i=0;i<e[x].size();i++){
int u=e[x][i].to,v=e[x][i].z;
if(d[u]>d[x]+v){
d[u]=d[x]+v;
if(!p[u]){
q[++l]=u;
p[u]=1;
}
}
}
p[x]=0;
}
for(int i=1;i<=n;i++)
if(d[i]<inf)
printf("%d ",d[i]);
else
printf("2147483647 ");
return 0;
}