Day4B队列和栈的使用

栈(stack):一种特殊线性数据结构,只允许在栈的一端插入或删除元素【栈顶】,另一端【栈底】
重要性质:先进后出,类似于往子弹夹装子弹然后发弹

递归:函数调用自身,一般解决有重复子问题的问题。
边界条件:什么情况下,函数不应该再继续调用自身

队列和栈

队列:

int q[1000], l = 0, r = 0;  // 初始化
q[r++] = x;  // 入队
int now = q[l];  // 获取队首
l++;  // 出队
q[r++] = y;
printf("%d\n", q[l++]); // 获取队首同时出队
if (l < r) {  // 判断是否为空
    printf("not empty\n");
}

栈:

int s[100], top = -1;
s[++top] = x;  // 入栈
int now = s[top]; // 获取栈顶元素
top--; // 出栈
s[++top] = y;
printf("%d\n", s[top--]);  // 获取栈顶同时出栈
if (top >= 0) {  // 栈不为空
    printf("not empty\n");
}

循环队列

const int size = 100000;
int q[size], l = 0, r = 0;  // 初始化
q[r] = x; r = (r + 1) % size;  // 入队
int now = q[l];  // 获取队首
l = (l + 1) % size;  // 出队
q[r] = y; r = (r + 1) % size;
printf("%d\n", q[l]); l = (l + 1) % size; // 获取队首同时出队
if (l != r) {  // 判断是否为空
    printf("not empty\n");
}

字符串栈:

char s[100][1000], top = -1;
scanf("%s", s[++top]);  // 入栈
char t[1000];
strcpy(t, s[top]); // 获取栈顶元素
top--; // 出栈
strcpy(s[++top], t);
printf("%s\n", s[top--]);  // 获取栈顶同时出栈
if (top >= 0) {  // 栈不为空
    printf("not empty\n");
}

报数(利用约瑟夫环)

有 n个小朋友做游戏,他们的编号分别是 1,2,3...n。他们按照编号从小到大依次顺时针围成一个圆圈,从第一个小朋友开始从 1 报数,依次按照顺时针方向报数(加一),报 m 的人会离开队伍,然后下一个小朋友会继续从 1 开始报数,直到只剩一个小朋友为止。

输入格式

第一行输入两个整数,n,m。( 10001≤n,m≤1000)

输出格式

输出最后一个小朋友的编号,占一行。

格式说明

输出时每行末尾的多余空格,不影响答案正确性

样例输入
10 5
样例输出

3

#include<stdio.h>
int ysfhuan(int n,int m, int i){
    if(i==1){
        return (m-1+n)%n;
    }
    return (ysfhuan(n-1,m,i-1)+m)%n;
    
}
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    printf("%d",ysfhuan(n,m,n)+1);
    return 0;
}

2.

有一种酒桌游戏叫做“敲7”,规则是从一个人开始,说出任意数字,其他人会顺序往后报,如果一个数字包含 7,或者是 7 的倍数,那么需要敲打杯子或盘子,不能说出。

现在 n 个人围坐在一个圆桌周围,他们编号从 1 到 n 顺时针排列。从某一人开始报出一个数字,其他人会按照顺时针方向顺序往后报(加一),如果某个人的数字包含 7,或者是 7 的倍数,那么他将退出游戏,下一个人继续接着报,直到剩一个人为止。

输入格式

第一行输入三个整数,n,m,t。n 代表总人数,m 代表从第 m 个人开始报数,他报出的数字是 t。(1≤m≤n≤1000,1≤t≤100)

接下来的 n 行,每一行输入一个字符串,代表这 n 个人的名字,字符串的长度不超过 20。

输出格式

输出剩下的那个人的名字,占一行。

格式说明

输出时每行末尾的多余空格,不影响答案正确性

样例输入
 
  1. 5 3 20

  2. donglali

  3. nanlali

  4. xilali

  5. beilali

  6. chuanpu

样例输出
chuanpu
    #include<stdio.h>
    const int L=1000;
    int main(){
        int n,m,t;
        int q[1000];
        scanf("%d %d %d",&n, &m, &t);
        char a[1000][21];
        int r,l;
        for(int i=1;i<=n;i++){
            scanf("%s",&a[i]);
        }
        for(int i=m;i<=n;i++){//入队
            q[r++]=i;
        }
        for(int i=1;i<m;i++){
            q[r++]=i;
        }
        while(n>1){
            int now=q[l++];//队首指针l
            l%=L;
            if(t%7 !=0 && t%10!=7 && t/10%10!=7 && t/100%10 !=7){//7的倍数不行
                q[r++] =now;
                r%=L;
            } else{
                n--;
            }
            t++;
        }
        printf("%s\n",a[q[l]]);
        return 0;
    }

3.计蒜客 – 快速匹配
问题描述

蒜头君在纸上写了一个串,只包含’(‘和’)’。一个’(‘能唯一匹配一个’)’,但是一个匹配的’(‘必须出现在’)’之前。请判断蒜头君写的字符串能否括号完全匹配,如果能,输出配对的括号的位置(匹配的括号不可以交叉,只能嵌套)。

输入格式

一行输入一个字符串只含有’(‘和’)’,输入的字符串长度不大于50000。

输出格式

如果输入括号不能匹配,输出一行”No”,否则输出一行”Yes”,接下里若干行每行输出 2个整数,用空格隔开,表示所有匹配对的括号的位置(下标从 1 开始)。你可以按照任意顺序输出。 本题答案不唯一,符合要求的答案均正确

样例输入

()()
1
样例输出

Yes
1 2
3 4
1
2
3
代码如下

#include<stdio.h>
int main(){
	int c[50000], top; // 存储左括号的位置的数组和栈顶指针
	char s[50001]; // 输入的字符串
	int zuo[50000], you[50000], lc, flag=1; // 记录左右括号匹配的数组和计数器及标记
	scanf("%s",s);
	// 遍历输入的字符串
	for(int i=0; s[i]; i++){
		if(s[i] == '(')
			c[top++] = i; // 如果是左括号,将其位置压入栈中
		else{
			if(top == 0){
				flag = 0; // 如果栈为空,说明匹配失败
				break;
			}
			// 弹出栈顶的左括号位置,并记录匹配的括号对位置
			zuo[lc] = c[--top];
			you[lc++] = i;
		}
	}
	if(top != 0)
		flag = 0; // 如果栈非空,说明匹配失败

	puts(flag ? "Yes" : "No"); // 输出匹配结果
	if(flag){
		// 输出匹配的括号对位置
		for(int i=0; i<lc; i++)
			printf("%d %d\n", zuo[i]+1, you[i]+1);
	}
	return 0;
}

4.计蒜客 – 网页跳转
题目要求:

蒜头君每天都在用一款名为“蒜厂浏览器”的软件。在这个浏览器中,一共三种操作:打开页面、回退和前进。它们的功能如下:

打开页面:在地址栏中输入网址,并跳转到网址对应的页面;
回退:返回到上一次访问的页面;
前进:返回到上次回退前的页面,如果上一次操作是打开页面,那么将无法前进。
现在,蒜头君打开浏览器,进行了一系列操作,你需要输出他每次操作后所在页面的网址。

输入格式

第一行输入一个整数n(0<n≤100000),表示蒜头君的操作次数。

接下来一共 n 行,每行首先输入一个字符串,如果是VISIT,后面接着输入一个不含有空格和换行的网址(网址长度小于100100),表示蒜头君在浏览器地址栏中输入的网址;如果是BACK,表示蒜头君点击了回退按钮;如果是FORWARD,表示蒜头君点击了前进按钮。

输出格式

对于每次操作,如果蒜头君能操作成功,输出蒜头君操作之后的网址,否则输出Ignore。假设蒜头君输入的所有网址都是合法的。

样例输入

10
VISIT https://www.jisuanke.com/course/476
VISIT https://www.taobao.com/
BACK
BACK
FORWARD
FORWARD
BACK
VISIT https://www.jisuanke.com/course/429
FORWARD
BACK


样例输出

https://www.jisuanke.com/course/476
https://www.taobao.com/
https://www.jisuanke.com/course/476
Ignore
https://www.taobao.com/
Ignore
https://www.jisuanke.com/course/476
https://www.jisuanke.com/course/429
Ignore
https://www.jisuanke.com/course/476

代码如下

#include <stdio.h>
#include <string.h>

int main()
{
	char http[100010][105]; 
	int n, f, top = -1, l = -1; // n为指令个数,f代表指令执行是否成功,top为栈顶指针,l为最后访问过的网页的索引
	char s[105]; // 存储指令字符串的数组

	scanf("%d", &n); // 输入指令个数
	while (n--)
	{
		scanf("%s", s); // 输入指令字符串

		if (s[0] == 'V') // 如果指令是“V”(Visit),表示访问网页
		{
			scanf("%s", http[++top]); // 输入要访问的网页,并存储到历史记录数组中
			l = top; // 更新最后访问网页的索引
			f = 1; // 将指令执行状态设置为成功
		}

		if (s[0] == 'B') // 如果指令是“B”(Back),表示返回上一页
		{
			if (top <= 0)
				f = 0; // 如果没有上一页可返回,将指令执行状态设置为失败
			else
			{
				top--; // 栈顶指针减1,表示返回上一页
				f = 1; // 将指令执行状态设置为成功
			}
		}

		if (s[0] == 'F') // 如果指令是“F”(Forward),表示前进到下一页
		{
			if (top < l) // 如果还有下一页可前进
			{
				top++; // 栈顶指针加1,表示前进到下一页
				f = 1; // 将指令执行状态设置为成功
			}
			else
				f = 0; // 如果没有下一页可前进,将指令执行状态设置为失败
		}

		if (f)
			printf("%s\n", http[top]); // 如果指令执行成功,则输出当前访问的网页
		else
			printf("Ignore\n"); // 如果指令执行失败,则输出忽略
	}

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值