前言:好不容易这次会这么多的题(偷溜出来打的,今天学校训练来着(线上讲题),对不住了朱哥T_T) 可恶的是就1:40,再多20分钟E就AC了。
A:
链接:https://ac.nowcoder.com/acm/contest/78306/A 利用a中的值,相加即可。类似于桶?
int n, m;
cin >> n >> m;
int a[N], b[N];
for(int i = 1 ;i <= n; i++) cin >> a[i];
int ans = 0;
for(int i = 0; i < m; i++) {
int x;
cin >> x;
ans += a[x];
}
cout << ans;
B:两种情况,一输一赢,胜者+3,败者+0.平,都加1
链接:https://ac.nowcoder.com/acm/contest/78306/B 来源:牛客网 如果平局,则获得的分数差值为0,如果不平局,分数差值为3.那么只要判断分数差值是否为3的倍数(0倍也是)即可
int x, y;
cin >> x >> y;
int t = abs(x - y);
if(t % 3 != 0) cout << "No\n";
else cout << "Yes\n";
C:(题目有点绕,看了半天题目才理解)给一个正整数n,要找到一个 最小的正整数 使得每一位都与原来的数不同。如果位数小于原来的数,那么要补上前缀0,且满足上述条件。
https://ac.nowcoder.com/acm/contest/78306/C 来源:牛客网
所以直接无脑找0呗,如果原序列未出现0,那么只用最后一位(个位)与原序列不同。注意0不是正数。
如果出现0,那要满足最小,就得把0改成1,然后非0改成0即可
string s, tmp;
cin >> s;
int jud = 0;
if(s.find('0') != string::npos) {
int t = s.find('0');
for(int i = t; i < s.size(); i++) {
if(s[i] == '0') tmp += "1";
else tmp += "0";
}
cout << tmp;
}
else {
s[s.size() - 1] == '1' ? cout << 2 : cout << 1;
//没找到0时,最后一位是1,必须输出2***
}
D:给m个区间,要求任意选取的区间(选或不选是两种),至少将n覆盖2次
链接:https://ac.nowcoder.com/acm/contest/78306/D 来源:牛客网
选或不选,利用递归枚举所有情况即可,每次递归到最后一层,进行差分即可。时间复杂度2^m + n
这边利用结构体进行存储左值和右值,利用bool数组进行枚举是否选择的情况。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
const int MOD = 998244353;
int n, m;
int sum = 0;
bool vis[20];
struct item {
int l;
int r;
}a[N];
void dfs(int x) {
if(x == m) {
int ans[N] = {0};
for(int i = 0; i < m; i++) {
if(vis[i] == true) {
ans[a[i].l] += 1;
ans[a[i].r + 1] -= 1;
}
}
for(int i = 1; i <= n; i++) {
ans[i] = ans[i] + ans[i - 1];
if(ans[i] < 2) return;
}
sum = (sum + 1) % MOD;
return;
}
vis[x] = false;
dfs(x + 1);
vis[x] = true;
dfs(x + 1);
}
void solve() {
cin >> n >> m;
for(int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
if(x > y) swap(x, y);
a[i] = {x, y};
}
dfs(0);
cout << sum;
}
int main() {
int T = 1;
// cin >> T;
while(T--) {
solve();
}
}
E 给出有序的a任务和b任务,要求是做了前一个a,才能做后一个a任务。而b任务可做可不做,但必须上面的a做了b才能做。q(10)次询问,长度为1e5,需要nlogn做法
链接:https://ac.nowcoder.com/acm/contest/78306/E 来源:牛客网
(感觉比D简单,如果你没学过差分的话)
思路:a必须一个一个做,而b可以选择性的做,那只需要暴力将每次的b进行排序即可,取第k小的和。于是转化到了一个经典问题:第k小数。优先队列维护第K小数即可
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
using i64 = int64_t;
i64 a[N], b[N];
void solve() {
i64 n, q;
cin >> n >> q;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) cin >> b[i];
for(int i = 0; i < q; i++) {
int x;
cin >> x;
priority_queue<int> pq;
i64 sum = 0;
i64 ans = INT_MAX;
for(int j = 1; j <= n; j++) {
if(pq.size() != x) {
pq.push(b[j]);
sum += b[j] + a[j];
ans = sum;
}
else {
sum += a[j];
if(b[j] < pq.top()) {
sum -= pq.top();
sum += b[j];
pq.pop();
pq.push(b[j]);
}
ans = min(ans, sum);
}
}
cout << ans << '\n';
}
}
int main() {
int T = 1;
while(T--) {
solve();
}
}