两道编程题的题解
密码生成
链接:https://www.nowcoder.com/questionTerminal/96bf0c548a094de7a05919e0b32b1a5a
来源:牛客网
小汪作为一个有数学天分的程序猿,设计了一套密码生成器来搞定自己的密码问题。
密码生成器由N个槽位组成,槽位的下标为0~N-1,每个槽位存储一个数。起初每个槽位都是0。
密码生成器会进行M轮计算,每轮计算,小汪会输入两个数L,R(L<=R),密码生成器会将这两个数作为下标,将两个下标之间(包含)的所有槽位赋值为i(i为当前的轮次,i∈[1,M])。
M轮计算完成后,密码生成器会根据槽位的最终值生成一条密码,密码的生成规则为:
(0*a[0] + 1*a[1] + 2*a[2] + ... + (N-1)*a[N-1]) mod 100000009
其中a[i]表示第i个槽位的最终值。
请帮助小汪把他的密码生成器实现为代码。
输入描述:
第一行为两个整数N,M,表示槽位个数和计算轮数。 接下来M行,每行两个整数Li,Ri,表示第i轮计算的输入。
输出描述:
输出一行,一个整数A,表示小汪的开机密码。
示例1
输入
5 3 2 3 1 2 1 1
输出
10
题解:排序+优先队列
#include <bits/stdc++.h>
using namespace std;
const int N = (int)2e5 + 5;
const int MOD = 100000009;
struct Segment {
int l, r, timer;
Segment() {}
Segment(int _l, int _r, int _timer) : l(_l), r(_r), timer(_timer) {}
bool operator< (const Segment& x) const {
return timer < x.timer;
}
}f[N];
int s[N];
priority_queue<Segment> que;
int main() {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 0; i < m; i++) {
int l, r;
scanf("%d %d", &l, &r);
f[i] = Segment(l, r, i + 1);
}
f[m] = Segment(0, n - 1, 0);
m++;
sort(f, f + m, [&](Segment x, Segment y) {
if (x.l == y.l) {
return x.r > y.r;
}
return x.l < y.l;
});
int cur = 0;
for (int i = 0; i < n; i++) {
while (cur < m && f[cur].l == i) {
que.push(f[cur]);
cur++;
}
while (que.top().r < i) que.pop();
s[i] = que.top().timer;
}
int ans = 0;
for (int i = 0; i < n; i++) {
ans = (ans + (i * 1LL * s[i]) % MOD) % MOD;
}
cout << ans << endl;
return 0;
}
IP过滤器
链接:https://www.nowcoder.com/questionTerminal/8389e1ccd47d40ba859c2497a428d0ca
来源:牛客网
在搜索引擎后端服务中,需要对恶意的抓取进行限制,其中的一个环节即对访问IP进行限制。请设计一个IP过滤器,实现对访问的IP限制的功能。对IP的限制数据有三种格式:
1.全IP:如222.205.58.16
2.前面带 *:如 *.58.16
3.后面带 *:如 222.205.58.*
带 * 的表示匹配到任意的IP段均可,且 * 可以代表多个ip段,且 * 只能出现在开头或者结尾。
现给出若干条需要过滤的规则,以及若干输入的IP,你需要输出这若干条IP是否会被过滤
输入描述:
输入的第一行是过滤规则的条数N和需要过滤的IP数量M,之后的N行为IP的过滤规则且均合法,再之后的M行为需要进行判断是否被过滤的IP。其中N<100,M<50。
输出描述:
0:该条IP不会被过滤 1:该条IP会被过滤 总共M条需要判断的IP需要以空格作为区分
示例1
输入
5 3 222.205.58.16 *.58.16 222.205.58.* *.16 224.* 222.205.58.17 222.205.59.19 223.205.59.16
输出
1 0 1
题解:暴力匹配即可
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
scanf("%d %d", &n, &m);
vector<string> foo, bar;
for (int i = 0; i < n; i++) {
string ss;
cin >> ss;
if (ss[0] == '*' || ss.back() == '*') {
foo.push_back(ss);
} else {
bar.push_back(ss);
}
}
auto ok = [&](string s1, string s2) -> bool {
if (s1[0] == '*') {
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end());
}
int i = 0, j = 0;
while (i < (int)s1.size() && j < (int)s2.size()) {
if (s1[i] == '*') {
return true;
}
if (s1[i] != s2[j]) {
return false;
}
i++;
j++;
}
return false;
};
auto check1 = [&](string ss) -> bool {
for (string b : bar) {
if (ss == b) {
return true;
}
}
return false;
};
auto check2 = [&](string ss) -> bool {
for (string f : foo) {
if (ok(f, ss)) {
return true;
}
}
return false;
};
for (int i = 0; i < m; i++) {
string ss;
cin >> ss;
if (check1(ss) || check2(ss)) {
cout << "1" << " ";
} else {
cout << "0" << " ";
}
}
cout << endl;
return 0;
}