牛客练习赛85 A~D题题解
Posted kaka0010
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客练习赛85 A~D题题解相关的知识,希望对你有一定的参考价值。
比赛链接:https://ac.nowcoder.com/acm/contest/11175
A 科学家的模型
模拟题,对每行数字和排序,最小值是1的肯定是9。
除去9之后,如果第3大和第4大相等,那么一定是8
之后全是0
#include <bits/stdc++.h>
using namespace std;
char mp[5][5];
int num[5];
int main() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
cin >> mp[i][j];
num[i] += mp[i][j] - '0';
}
}
sort(num, num + 5);
if (num[0] == 1) cout << 9 << endl;
else if (num[2] == num[3]) cout << 8 << endl;
else cout << 0 << endl;
}
B 音乐家的曲调
考虑DP
我们找每个点可以到达的最前面那个点,然后列出方程转移一下。
f
[
i
]
[
3
]
=
m
a
x
(
f
[
i
−
1
]
[
3
]
,
f
[
p
r
e
−
1
]
[
2
]
+
(
i
−
p
r
e
+
1
)
)
f[i][3]=max(f[i-1][3],f[pre-1][2]+(i-pre+1))
f[i][3]=max(f[i−1][3],f[pre−1][2]+(i−pre+1))
f [ i ] [ 2 ] = m a x ( f [ i − 1 ] [ 2 ] , f [ p r e − 1 ] [ 2 ] + ( i − p r e + 1 ) ) f[i][2]=max(f[i-1][2],f[pre-1][2]+(i-pre+1)) f[i][2]=max(f[i−1][2],f[pre−1][2]+(i−pre+1))
f [ i ] [ 1 ] = m a x ( f [ i − 1 ] [ 1 ] , f [ p r e − 1 ] [ 2 ] + ( i − p r e + 1 ) ) f[i][1]=max(f[i-1][1],f[pre-1][2]+(i-pre+1)) f[i][1]=max(f[i−1][1],f[pre−1][2]+(i−pre+1))
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e7 + 10;
const int MOD = 1e9 + 7;
char s[N];
int pre[N], lmax[N];
int dp[N][4];
queue<int> que[26];
void solve () {
int n, m; cin >> n >> m;
cin >> (s + 1);
lmax[0] = 1;
for (int i = 1; i <= n; i++) {
que[s[i]-'a'].push(i);
lmax[i] = max(lmax[i], lmax[i-1]);
if (que[s[i]-'a'].size() > m) {
int now = que[s[i]-'a'].front();
que[s[i]-'a'].pop();
pre[i] = now;
lmax[i] = max(lmax[i], pre[i] + 1);
}
}
//for (int i = 1; i <= n; i++) cout << lmax[i] << endl;
for (int i = 1; i <= n ;i++) {
dp[i][3] = max(dp[i-1][3], dp[lmax[i] - 1][2] + (i - lmax[i] + 1));
dp[i][2] = max(dp[i-1][2], dp[lmax[i] - 1][1] + (i - lmax[i] + 1));
dp[i][1] = max(dp[i-1][1], dp[lmax[i] - 1][0] + (i - lmax[i] + 1));
}
cout << dp[n][3] << endl;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
return 0;
}
C 哲学家的沉思
转化一下题意变成找每个数后第一个大于它的数。
然后用nxt数组串起来,倍增处理一下之后暴力跳就可以了。
f [ i ] [ j ] = f [ f [ i ] [ j − 1 ] ] [ j − 1 ] f[i][j]=f[f[i][j-1]][j-1] f[i][j]=f[f[i][j−1]][j−1]
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e7 + 10;
const int MOD = 1e9 + 7;
int r[N], a[N], stk[N], top;
int f[N][21];
void solve () {
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
a[n+1] = INF;
for (int i = 1; i <= n + 1; i++) {
while (top && a[i] > a[stk[top]]) r[stk[top]] = i, f[stk[top]][0] = i, top--;
stk[++top] = i;
}
for (int i = 0; i <= 20; i++) f[n][i] = f[n+1][i] = n + 1;
for (int j = 1; j <= 20; j++) {
for (int i = 1; i <= n; i++) {
f[i][j] = f[f[i][j-1]][j-1];
}
}
for (int i = 1; i <= m; i++) {
int L, R; cin >> L >> R;
int now = L, ans = 0;
for (int j = 20; ~j; j--) {
if (f[now][j] <= R) {
ans += (1 << j);
now = f[now][j];
}
}
cout << ans + 1 << endl;
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
return 0;
}
D 数学家的迷题
查询区间积后素因子的个数。
本来最早的想法是主席树,但有修改就显得很麻烦了,瞄了一眼题解发现了bitset,马上就懂了。
我们只要把pushup中的bitset进行或运算即可,质因数分解常数太大还tle好多次。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
const int MOD = 1e9 + 7;
int prime[N], cnt, tot, a[N];
bool is_prime[N];
unordered_map<int, int> mp;
void get_prime(){
memset(is_prime, true, sizeof is_prime);
is_prime[0] = is_prime[1] = false;
for(int i = 2 ; i < N;i++){
if (is_prime[i]) prime[++cnt] = i;
for(int j = 1; j <= cnt && 1ll * i * prime[j] < N;j++){
is_prime[i * prime[j]] = false;
if(i % prime[j] == 0) break;
}
}
}
struct node {
int l, r;
bitset<10005> bi;
}t[50005 << 2];
void push_up(int u) {
t[u].bi = t[u<<1].bi | t[u<<1|1].bi;
}
void build(int u, int l, int r) {
t[u].l = l, t[u].r = r;
if (l == r) return;
int mid = (l + r) >> 1;
build(u<<1, l, mid);
build(u<<1|1, mid+1, r);
}
void add(int u, int pos, int y) {
if (t[u].l == t[u].r) {
t[u].bi.set(y);
return;
}
int mid = (t[u].l + t[u].r) >> 1;
if (pos <= mid) add(u<<1, pos, y);
else add(u<<1|1, pos, y);
push_up(u);
}
void reset(int u, int pos) {
if (t[u].l == t牛客练习赛82总结+题解(只有A题Mocha 的字符串)