队列 手算到机算 入门 队列 循环队列

队列 手算到机算 入门   队列   循环队列

总目录:从手算到机算 算法竞赛入门篇

队列:先进先出

1.洛谷   P1996 约瑟夫问题

 

队列写法如下

手算过程如下:

输入:
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;
} 

2.洛谷 P1540 机器翻译

队列写法如下

手算过程如下:

整个查字典过程如下:每行表示一个单词的翻译,冒号前为本次翻译后的内存状况:

    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;
}

3.洛谷 P1162 填涂颜色

样例模拟如下:

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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值