队列 手算到机算 入门 队列 循环队列
总目录:从手算到机算 算法竞赛入门篇
队列:先进先出
队列写法如下
手算过程如下:
输入:
10 3
输出:
3 6 9 2 7 1 8 5 10 4
h代表队首,t代表队尾
队列如下:h=1,t=11
位置1 2 3 4 5 6 7 8 9 10
数值1 2 3 4 5 6 7 8 9 10
报数1:h=2,t=12
位置2 3 4 5 6 7 8 9 10 11
数值2 3 4 5 6 7 8 9 10 1
报数2:h=3,t=13
位置3 4 5 6 7 8 9 10 11 12
数值3 4 5 6 7 8 9 10 1 2
报数3.h=4,t=13
3出列
位置4 5 6 7 8 9 10 11 12
数值4 5 6 7 8 9 10 1 2
报数1:h=5,t=14
位置5 6 7 8 9 10 11 12 13
数值5 6 7 8 9 10 1 2 4
报数2:h=6,t=15
位置6 7 8 9 10 11 12 13 14
数值6 7 8 9 10 1 2 4 5
报数3.
6出列:h=7,t=15
位置7 8 9 10 11 12 13 14
数值7 8 9 10 1 2 4 5
以此类推......
AC代码如下:
#include <bits/stdc++.h>
int q[10010];
int main(){
int n,m,i,h,t,cnt;
scanf("%d%d",&n,&m);
h=1;
for(i=1;i<=n;i++)q[i]=i;
t=n+1,cnt=0;
while(h<t){
cnt++;
if(cnt==m){
printf("%d ",q[h]);
cnt=0,h++;
}else{
q[t]=q[h];
h++,t++;
}
}
return 0;
}
循环队列写法如下
手算过程如下:
输入:
10 3
输出:
3 6 9 2 7 1 8 5 10 4
循环队列如下:h=0,t=10
位置0 1 2 3 4 5 6 7 8 9 10
数值1 2 3 4 5 6 7 8 9 10
报数1:h=1,t=0
位置0 1 2 3 4 5 6 7 8 9 10
数值1 2 3 4 5 6 7 8 9 10 1
报数2:h=2,t=1
位置0 1 2 3 4 5 6 7 8 9 10
数值2 2 3 4 5 6 7 8 9 10 1
报数3:h=3,t=1,3出列
位置0 1 2 3 4 5 6 7 8 9 10
数值2 2 3 4 5 6 7 8 9 10 1
报数1:h=4,t=2
位置0 1 2 3 4 5 6 7 8 9 10
数值2 4 3 4 5 6 7 8 9 10 1
报数2:h=5,t=3
位置0 1 2 3 4 5 6 7 8 9 10
数值2 4 5 4 5 6 7 8 9 10 1
依次类推
......
AC代码如下:
#include <stdio.h>
int q[110],h,t;
int main(){
int n,m,i,cnt;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)q[i]=i+1;
h=0,t=n,cnt=0;
while(h!=t){
cnt++;
if(cnt==m)cnt=0,printf("%d ",q[h]);
else{
q[t]=q[h];
t=(t+1)%(n+1);
}
h=(h+1)%(n+1);
}
return 0;
}
队列写法如下
手算过程如下:
整个查字典过程如下:每行表示一个单词的翻译,冒号前为本次翻译后的内存状况:
1:查找单词 1 并调入内存。
1 2:查找单词 2 并调入内存。
1 2:在内存中找到单词 1。
1 2 5:查找单词 5 并调入内存。
2 5 4:查找单词 4 并调入内存替代单词 1。
2 5 4:在内存中找到单词 4。
5 4 1:查找单词 1 并调入内存替代单词 2。
AC代码如下:
#include <stdio.h>
int m,n;
int q[1010],h,t;
int main(){
int i,x,j,cnt;
scanf("%d%d",&m,&n);
h=t=1,cnt=0;
for(i=1;i<=n;i++){
scanf("%d",&x);
for(j=h;j<t;j++)//队列中查找
if(q[j]==x)break;
if(j==t){//内存中未找到
cnt++;
if(t-h==m)h++,q[t]=x,t++;//内存已满
else q[t]=x,t++;//内存未满
}
}
printf("%d\n",cnt);
return 0;
}
样例模拟如下:
6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
遇到外围的0,变成-1
-1 -1 -1 -1 -1 -1
-1 -1 1 1 1 1
-1 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1
打印时,
遇到-1,打印0.
遇到1,打印1.
遇到0,打印2.
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1
AC代码如下:
#include <bits/stdc++.h>
#define maxn 35
int a[maxn][maxn],n;
int h,t;
struct node{
int r,c;
}q[maxn*maxn];
int next[][2]={{-1,0},{1,0},{0,-1},{0,1}};
void bfs(int r,int c){
int nr,nc,rr,cc,i;
h=t=1;
q[t].r=r,q[t].c=c,t++;
while(h<t){
rr=q[h].r,cc=q[h].c;
for(i=0;i<4;i++){
nr=rr+next[i][0],nc=cc+next[i][1];
if(1<=nr&&nr<=n&&1<=nc&&nc<=n&&!a[nr][nc])
a[nr][nc]=-1,q[t].r=nr,q[t].c=nc,t++;
}
h++;
}
}
int main(){
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for(j=1;j<=n;j++)
if(!a[1][j])bfs(1,j);
for(j=1;j<=n;j++)
if(!a[n][j])bfs(n,j);
for(i=1;i<=n;i++)
if(!a[i][1])bfs(i,1);
for(i=1;i<=n;i++)
if(!a[i][n])bfs(i,n);
for(i=1;i<=n;i++){
for(j=1;j<=n;j++)
if(a[i][j]==-1)printf("0 ");
else if(!a[i][j])printf("2 ");
else printf("1 ");
printf("\n");
}
return 0;
}