2、算法练习专栏——牛客练习——天梯备赛03
A
题目描述
对输入的字符串进行排序后输出
打开以下链接可以查看正确的代码
1 |
|
输入描述:
1 |
|
输出描述:
1 |
|
示例1
输入
1 |
|
输出
1 |
|
代码
1 |
|
B
大雄喜欢二进制。
大雄面前有一个 nnn 个数的序列 aaa,对于一个区间 [l,r][l,r][l,r],设
ans=(al and al+1 and……and ar−1 and ar)+(al or al+1 or……or ar−1 or ar)ans=(a_l\ \text{and}\ a_{l+1}\ \text{and}……\text{and}\ a_{r-1}\ \text{and}\ a_r ) +(a_l\ \text{or}\ a_{l+1}\ \text{or}……\text{or}\ a_{r-1}\ \text{or}\ a_r)ans=(al and al+1 and……and ar−1 and ar)+(al or al+1 or……or ar−1 or ar)
输出最大的 ansansans 值。
输入描述:
1 |
|
输出描述:
1 |
|
示例1
输入
1 |
|
输出
1 |
|
代码
1 |
|
C
题目描述
ZZT 创造了一个队列 Q。这个队列包含了 N 个元素,队列中的第 i 个元素用 Qi 表示。Q1 表示队头元素,QN 表示队尾元素。队列中的元素是 N 的一个全排列。
ZZT 需要在这个队列上执行 P 次操作,操作分两种:
FIRST X: 将元素 X 移到队头。
LAST X: 将元素 X 移到队尾。
在 P 次操作之后,ZZT 想知道队列中的元素的排列方式,由于他最近很忙,因此需要请你帮他解决这个问题。
输入描述:
1 |
|
输出描述:
1 |
|
示例1
输入
1 |
|
输出
1 |
|
代码
1 |
|
D
题目描述
在进行文法分析的时候,通常需要检测一个单词是否在我们的单词列表里。为了提高查找和定位的速度,通常都要画出与单词列表所对应的单词查找树,其特点如下:
l 根节点不包含字母,除根节点外每一个节点都仅包含一个大写英文字母;
l 从根节点到某一节点,路径上经过的字母依次连起来所构成的字母序列,称为该节点对应的单词。单词列表中的每个词,都是该单词查找树某个节点所对应的单词;
l 在满足上述条件下,该单词查找树的节点数最少。
例:图一的单词列表对应图二的单词查找树
对一个确定的单词列表,请统计对应的单词查找树的节点数(包括根节点)
输入描述:
1 |
|
输出描述:
1 |
|
示例1
输入
1 |
|
输出
1 |
|
代码
1 |
|
E
链接:https://ac.nowcoder.com/acm/contest/75962/E
来源:牛客网
题目描述
给定n个字符串,互不相等,你可以任意指定字符之间的大小关系(即重定义字典序),求有多少个串可能成为字典序最小的串,并输出它们
输入描述:
1 |
|
输出描述:
1 |
|
示例1
输入
1 |
|
输出
1 |
|
备注:
1 |
|
代码
1 |
|
扩展
一、模拟散列表(简单+)
维护一个集合,支持如下几种操作:
I x
,插入一个整数 x;Q x
,询问整数 x 是否在集合中出现过;
现在要进行 N 次操作,对于每个询问操作输出对应的结果。
输入格式
第一行包含整数 N,表示操作数量。
接下来 N 行,每行包含一个操作指令,操作指令为 I x
,Q x
中的一种。
输出格式
对于每个询问指令 Q x
,输出一个询问结果,如果 x 在集合中出现过,则输出 Yes
,否则输出 No
。
每个结果占一行。
数据范围
1≤N≤10^5^
−10^9^≤x≤10^9^
输入样例:
1 |
|
输出样例:
1 |
|
思路
- 思路一(无脑): 使用< map > 或者 < unordered_map>
- 思路二(哈希): 使用拉链法的思想
- 思路三(哈希): 使用寻址法的思想
代码
思路一答案(请自己先思考一下再参考)
#include < iostream> #include < algorithm> #include < unordered_map> using namespace std; const int N = 1e5 + 10; map Map; int n; int main() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin >> n; while (n--) { char op[2]; int x; cin >> op >> x; if (op[0] == 'I') { Map[x] = x; if (x == 0) Map[x] = 1; } else if (Map[x] == 0) cout << "No\n"; else cout << "Yes\n"; } return 0; }
思路二答案(请自己先思考一下再参考)
#include < iostream> #include < algorithm> #include < cstring> using namespace std; const int N = 100003; int arr[N], e[N], ne[N], idx; int n; void insert(int x) { int k = (x % N + N) % N; e[idx] = x; ne[idx] = arr[k]; arr[k] = idx++; } bool find(int x) { int k = (x % N + N) % N; for (int i = arr[k]; ~i; i = ne[i]) { if (e[i] == x) return true; } return false; } int main() { cin >> n; memset(arr, -1, sizeof arr); for (int i = 0; i < n; i++) { char op[2]; int x; scanf("%s%d", op, &x); if (op[0] == 'I') insert(x); else { if (find(x)) printf("Yes\n"); else printf("No\n"); } } return 0; }
思路三答案(请自己先思考一下再参考)
#include < iostream> #include < algorithm> #include < cstring> using namespace std; const int null = 0x3f3f3f3f; const int N = 200003; int h[N]; int n; int find(int x) { int k = (x % N + N) % N; while (h[k] != null && h[k] != x) { k++; if (N == k) k = 0; } return k; } int main() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin >> n; memset(h, 0x3f, sizeof h); while (n--) { char op[2]; int x; cin >> op >> x; if (*op == 'I') { int k = find(x); h[k] = x; } else { if (h[find(x)] != null) cout << "Yes\n"; else cout << "No\n"; } } return 0; }
二、哈希字符串
给定一个长度为 n 的字符串,再给定 m 个询问,每个询问包含四个整数 l1,r1,l2,r2请你判断 [l1,r1] [1,1] 和 [l2,r2] [2,2] 这两个区间所包含的字符串子串是否完全相同。
字符串中只包含大小写英文字母和数字。
输入格式
第一行包含整数 n 和 m,表示字符串长度和询问次数。
第二行包含一个长度为 n 的字符串,字符串中只包含大小写英文字母和数字。
接下来 m 行,每行包含四个整数 l1,r1,l2,表示一次询问所涉及的两个区间。
注意,字符串的位置从 11 开始编号。
输出格式
对于每个询问输出一个结果,如果两个字符串子串完全相同则输出 Yes
,否则输出 No
。
每个结果占一行。
数据范围
1≤n,m≤10^5^
输入样例:
1 |
|
输出样例:
1 |
|
思路
求哈希值
代码
答案(请自己先思考一下再参考)
#include < iostream> #include < algorithm> using namespace std; typedef unsigned long long ULL; const int N = 1e5 + 10, P = 131; char str[N]; ULL p[N], h[N]; int n, m; ULL get(int l, int r) { return h[r] - h[l - 1] * p[r - l + 1]; } int main() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin >> n >> m >> str + 1; p[0] = 1; for (int i = 1; i <= n; i++) { p[i] = p[i - 1] * P; h[i] += h[i - 1] * P + str[i]; } while (m--) { int l1, r1, l2, r2; cin >> l1 >> r1 >> l2 >> r2; if (get(l1, r1) == get(l2, r2)) puts("Yes"); else puts("No"); } return 0; }