24-1-26学习总结

 学习记录

队列

通常是要定义一个头指针,一个尾指针,在操作的时候分别对其进行操作,(虽然会占用空间较多,但是时间会比较节约)当head头指针与tail尾指针相遇的时候代表队列为空,结束。

队列遵循“先进先出”的原则(First In First Out)

通常可以把队列的三个基本元素(一个数组,两个变量(头指针尾指针))放在结构体内,就可以简单对队列进行操作。

typedef struct quene {
	int data[100];
	int head;
	int tail;
}Qe;
//队列初学习
typedef struct quene {
	int data[100];
	int head;
	int tail;
}Qe;
int main()
{
	Qe q;
	q.head = 1;
	q.tail = 1;
	for (int i = 0; i < 9; i++)
	{
		scanf("%d", &q.data[q.tail]);
		q.tail++;
	}
	while (q.head < q.tail)
	{
		printf("%d ", q.data[q.head]);
		q.head++;
		q.data[q.tail] = q.data[q.head];
		q.tail++;
		q.head++;
	}
	return 0;
}

栈不同于队列的先进先出,而是后进先出。(可以想象成一个筐子,先放进去的沉在最底下,后放进去的在最上面)

栈的初认识
int main()
{
	char a[100] = { 0 }, s[100] = { 0 };
	gets(a);
	int len = strlen(a);
	int mid = len / 2 - 1;
	int top = 0;
	for (int i = 0; i <= mid; i++)
	{
		s[++top] = a[i];
	}
	int next = 0;
	if (len % 2 == 0)
		next = mid + 1;
	else
		next = mid + 2;
	for (int i = next; i < len ; i++)
	{
		if (s[top] != a[i])
			break;
		top--;
	}
 	if (top == 0)
		printf("YES");
	else
		printf("NO");
	return 0;
}

 啊哈算法----小猫钓鱼

typedef struct quene    //两个人手上的牌
{
	int data[1000];
	int head;
	int tail;
}Qun;
typedef struct stack    //桌面上的牌最多就只有10张 因为牌面是0-9
{
	int data[100];
	int top;
}Stk;
int main()
{
	Qun q1, q2;
	Stk s;
	int book[10] = { 0 };
	q1.head = 1;
	q1.tail = 1;
	q2.head = 1;
	q2.tail = 1;
	s.top = 0;
	int t = 0;

	for (int i = 0; i < 6; i++)
	{
		scanf("%d", &q1.data[q1.tail]);
		q1.tail++;
	}
	for (int i = 0; i < 6; i++)
	{
		scanf("%d", &q2.data[q2.tail]);
		q2.tail++;
	}
	
	while (q1.head < q1.tail && q2.head < q2.tail)
	{
		t = q1.data[q1.head];
		if (book[t] == 0)  //1没有赢牌
		{
			q1.head++;
			s.top++;
			s.data[s.top] = t;
			book[t] = 1;
		}
		else  //1赢牌了,需要拿牌
		{
			q1.head++;
			q1.data[q1.tail] = t;
			q1.tail++;
			while (s.data[s.top] != t)
			{
				book[s.data[s.top]] = 0;
				q1.data[q1.tail] = s.data[s.top];
				q1.tail++;
				s.top--;
			}
			book[s.data[s.top]] = 0;
			q1.data[q1.tail] = s.data[s.top];
			q1.tail++;
			s.top--;
		}
		if (q1.head == q1.tail)  
			break;

		t = q2.data[q2.head];
		if (book[t] == 0)  //2没有赢牌
		{
			q2.head++;
			s.top++;
			s.data[s.top] = t;
			book[t] = 1;
		}
		else  //2赢牌了,需要拿牌
		{
			q2.head++;
			q2.data[q2.tail] = t;
			q2.tail++;
			while (s.data[s.top] != t)
			{
				book[s.data[s.top]] = 0;
				q2.data[q2.tail] = s.data[s.top];
				q2.tail++;
				s.top--;
			}
			book[s.data[s.top]] = 0;
			q2.data[q2.tail] = s.data[s.top];
			q2.tail++;
			s.top--;
		}
	}
	if (q2.head == q2.tail)
	{
		printf("1 win\n");
		printf("1当前手上的牌为:");
		for (int i = q1.head; i <= q1.tail - 1; i++)
		{
			printf("%d ", q1.data[i]);
		}
		if (s.top > 0)
		{
			printf("\n桌上的牌是:");
			for (int i = 1; i <= s.top; i++)
			{
				printf("%d ", s.data[i]);
			}
		}
		else
			printf("\n桌上没有牌了");
	}
	else
	{
		printf("2 win\n");
		printf("2当前手上的牌为:");
		for (int i = q2.head; i <= q2.tail - 1; i++)
		{
			printf("%d ", q2.data[i]);
		}
		if (s.top > 0)
		{
			printf("\n桌上的牌是:");
			for (int i = 1; i <= s.top; i++)
			{
				printf("%d ", s.data[i]);
			}
		}
		else
			printf("\n桌上没有牌了");
	}
	return 0;
}

测试题

P1055 [NOIP2008 普及组] ISBN 号码

# [NOIP2008 普及组] ISBN 号码

## 题目描述

每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 $9$ 位数字、$1$ 位识别码和 $3$ 位分隔符,其规定格式如 `x-xxx-xxxxx-x`,其中符号 `-` 就是分隔符(键盘上的减号),最后一位是识别码,例如 `0-670-82162-4`就是一个标准的 ISBN 码。ISBN 码的首位数字表示书籍的出版语言,例如 $0$ 代表英语;第一个分隔符 `-` 之后的三位数字代表出版社,例如 $670$ 代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。

识别码的计算方法如下:

首位数字乘以 $1$ 加上次位数字乘以 $2$ ……以此类推,用所得的结果 $ \bmod 11$,所得的余数即为识别码,如果余数为 $10$,则识别码为大写字母 $X$。例如 ISBN 号码 `0-670-82162-4` 中的识别码 $4$ 是这样得到的:对 `067082162` 这 $9$ 个数字,从左至右,分别乘以 $1,2,\dots,9$ 再求和,即 $0\times 1+6\times 2+……+2\times 9=158$,然后取 $158 \bmod 11$ 的结果 $4$ 作为识别码。

你的任务是编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出 `Right`;如果错误,则输出你认为是正确的 ISBN 号码。

## 输入格式

一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式要求)。

## 输出格式

一行,假如输入的 ISBN 号码的识别码正确,那么输出 `Right`,否则,按照规定的格式,输出正确的 ISBN 号码(包括分隔符 `-`)。

## 样例 #1

### 样例输入 #1

```
0-670-82162-4
```

### 样例输出 #1

```
Right
```

## 样例 #2

### 样例输入 #2

```
0-670-82162-0
```

### 样例输出 #2

```
0-670-82162-4
```

## 提示

2008 普及组第一题

P1055 [NOIP2008 普及组] ISBN 号码
int main()
{
	char str[20];
	gets(str);
	int len = strlen(str);
	int a[11];
	int t = 1;
	int sum = 0;
	for (int i = 0; i < len; i++)
	{
		if (str[i] >= '0' && str[i] <= '9')
		{
			a[t] = str[i] - '0';
			t++;
		}
	}
	for (int i = 1; i <= 9; i++)
	{
		sum += a[i] * i;
	}
	int b = sum % 11;
	if (b == a[10])
	{
		printf("Right");
	}
	else
	{
		str[len - 1] = (b + '0');
		printf("%s", str);
	}
	return 0;
}

 P9064 [yLOI2023] 苦竹林

# [yLOI2023] 苦竹林

## 题目背景

> 悬挂在屋檐下的风铃,摇晃的声音很动听。  
> 思念就像梅雨下不停,我的心境一片泥泞。  
> 散落在天际里的繁星,闪烁着你我的宿命。  
> 当枫叶轻盈落入湖心,近看山水一片宁静。  

——银临 & 涵昱《苦竹林》

## 题目描述

共有 $n$ 个风铃悬挂在屋檐下,每个风铃都能发出一定音调的声音。从左到右给风铃从 $1$ 至 $n$ 编号,第 $i$ 个风铃的音调是 $a_i$。

为了表达内心的思念,扶苏决定在 $n$ 个的风铃中取出 $m$ 个,送给远方的朋友。

请你找到最小的整数 $\varepsilon$,使得存在一种方案,能够从 $n$ 个风铃中挑出 $m$ 个,设挑出风铃的音调为 $b_1, b_2, \dots b_m$,满足对任意的 $1 \leq i, j \leq m$,都有 $|b_i - b_j| \leq \varepsilon$。

## 输入格式

第一行是两个整数,表示风铃的个数 $n$ 和挑选出风铃的个数 $m$。  
第二行有 $n$ 个整数,表示每个风铃的音调。第 $i$ 个整数表示 $a_i$。

## 输出格式

输出一行一个整数,表示最小的 $\varepsilon$。

## 样例 #1

### 样例输入 #1

```
5 3
1 2 3 4 5
```

### 样例输出 #1

```
2
```

## 样例 #2

### 样例输入 #2

```
6 4
1 7 8 3 4 6
```

### 样例输出 #2

```
4
```

## 提示

### 样例 2 解释

一种选择的方案是选择第 $2,4,5,6$ 四个风铃,音调依次为 $7,3,4,6$。可以得到对任何的 $1 \leq i, j\leq 4$,都有 $|b_i - b_j| \leq 4$。

另一种方案是选择第 $2,3,5,6$ 四个风铃,同样计算得到的 $\varepsilon$ 为 $4$。

### 数据规模与约定

- 对 $10\%$ 的数据,$m = 2$。
- 另有 $10\%$ 的数据,$m = n$。
- 对 $40\%$ 的数据,$n \leq 5$。
- 对 $60\%$ 的数据,保证对所有的 $2 \leq i \leq n$,满足 $a_{i - 1} \leq a_i$,即 $a_i$ 单调不降。
- 对 $80\%$ 的数据,$n \leq 10^3$。
- 对 $100\%$ 的数据,$2 \leq m \leq n \leq 10^5$,$1 \leq a_i \leq 10^9$。

### 说明

本题共有三个附加样例文件,见题目附件中的 `ring.zip`。

P9064 [yLOI2023] 苦竹林
int main()
{
	int n = 0, m = 0; //风铃数n  取m
	int a[100001];
	scanf("%d%d", &n, &m);
	int num = 0;
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n-1-i; j++)
		{
			if (a[j] > a[j + 1])
			{
				int t = a[j];
				a[j] = a[j + 1];
				a[j + 1] = t;
			}
		}
	}
	if (n % 2 != 0)
	{
		int mid = (n - 1) / 2;
		if (m % 2 != 0)
		{
			int t = (m - 1) / 2;
			num = a[mid + t] - a[mid - t];
			printf("%d", num);
		}
		else
		{
			int t = m / 2;
			int num1 = 0, num2 = 0;
			num1 = a[mid + t] - a[mid + 1 - t];
			num2 = a[mid - 1 + t] - a[mid - t];
			if (num1 > num2)
				num = num1;
			else
				num = num2;
			printf("%d", num);
		}
	}
	else if (n % 2 == 0)
	{
		int mid1 = n / 2 - 1;
		int mid2 = n / 2;
		if (m % 2 == 0)
		{
			int t = (m - 2) / 2;
			num = a[mid2 + t] - a[mid1 - t];
			printf("%d", num);
		}
		else
		{
			int t = (m - 2 + 1) / 2;
			int num1 = a[mid2 - 1 + t] - a[mid1 - t];
			int num2 = a[mid2 + t] - a[mid1 + 1 - t];
			if (num1 > num2)
				num = num1;
			else
				num = num2;
			printf("%d", num);
		}
	}
	return 0;
}

 P2032 扫描

# 扫描

## 题目描述

有一个 $1 \times n$ 的矩阵,有 $n$ 个整数。

现在给你一个可以盖住连续 $k$ 个数的木板。

一开始木板盖住了矩阵的第 $1 \sim k$ 个数,每次将木板向右移动一个单位,直到右端与第 $n$ 个数重合。

每次移动前输出被覆盖住的数字中最大的数是多少。

## 输入格式

第一行两个整数 $n,k$,表示共有 $n$ 个数,木板可以盖住 $k$ 个数。

第二行 $n$ 个整数,表示矩阵中的元素。

## 输出格式

共 $n - k + 1$ 行,每行一个整数。

第 $i$ 行表示第 $i \sim i + k - 1$ 个数中最大值是多少。

## 样例 #1

### 样例输入 #1

```
5 3
1 5 3 4 2
```

### 样例输出 #1

```
5
5
4
```

## 提示

对于 $20\%$ 的数据,$1 \leq k \leq n \leq 10^3$。

对于 $50\%$ 的数据,$1 \leq k \leq n \leq 10^4$。

对于 $100\%$ 的数据,$1 \leq k \leq n \leq 2 \times 10^6$,矩阵中的元素大小不超过 $10^4$ 并且均为正整数。

//P2032 扫描
int main()
{
	int n = 0, k = 0, max = 0;
	scanf("%d%d", &n, &k);
	int a[100] = { 0 };
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
	}
	for (int i = 0; i < n - k + 1; i++)
	{
		max = a[i];
		for (int j = i; j <	i + k; j++)
		{
			if (max < a[j])
				max = a[j];
		}
		printf("%d\n", max);
	}
	return 0;
}

 P4387 【深基15.习9】验证栈序列

# 【深基15.习9】验证栈序列

## 题目描述

给出两个序列 pushed 和 poped 两个序列,其取值从 1 到 $n(n\le100000)$。已知入栈序列是 pushed,如果出栈序列有可能是 poped,则输出 `Yes`,否则输出 `No`。为了防止骗分,每个测试点有多组数据。

## 输入格式

第一行一个整数 $q$,询问次数。

接下来 $q$ 个询问,对于每个询问:

第一行一个整数 $n$ 表示序列长度;

第二行 $n$ 个整数表示入栈序列;

第三行 $n$ 个整数表示出栈序列;

## 输出格式

对于每个询问输出答案。

## 样例 #1

### 样例输入 #1

```
2
5
1 2 3 4 5
5 4 3 2 1
4
1 2 3 4
2 4 1 3
```

### 样例输出 #1

```
Yes
No
```

int main()
{
	int q = 0;
	scanf("%d", &q);
	for (int k = 0; k < q; k++)
	{
		int n = 0, t = 0;
		scanf("%d", &n);
		int a[1000] = { 0 }, b[1000] = { 0 };
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &a[i]);
			t++;
		}
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &b[i]);
		}
		int key = 0;
		for (int i = 0; i < n; i++)
		{
			t--;
			if (a[t] != b[i])
			{
				key = 1;
				break;	
			}
		}
		if (key == 0)
			printf("YES\n");
		else if(key==1)
			printf("NO\n");
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值