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