2023牛客算法基础训练营补题5
A
solve
二分+前缀和,签到
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int s[N];
int pre[N];
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, q;
cin >> n >> q;
for (int i = 1; i <= n; i++) {
cin >> s[i];
}
sort(s + 1, s + 1 + n);
for (int i = 1; i <= n; i++)
pre[i] = pre[i - 1] + s[i];
while (q--) {
int k, x;
cin >> k >> x;
int l = 1, r = n;
while (l < r) {
int mid = l + r >> 1;
if (s[mid] > x)
r = mid;
else
l = mid + 1;
}
if (s[l] > x)
l--;
if (k <= l)
cout << pre[l] - pre[l - k] << endl;
else
cout << pre[l] << endl;
}
return 0;
}
// 题目所考察知识:
// 心得体会:
B
solve
由于字典序小的获胜,所以每次行动最优都是只拿一个放入该格子
最后只需要比较奇偶即可
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
if(n % 2 == 1) cout << "Yaya-win!" << endl;
else cout << "win-win!" << endl;
return 0;
}
//题目所考察知识:
//心得体会:
K
solve
显然每次行动的最优指令是 n/2 + 1,这样可以保证淘汰最多的人
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0);
int n;
n = read();
int res = 0;
while (n > 2) {
n = n / 2 + 1;
res += 1;
}
printf("%d\n", res);
return 0;
}
// 题目所考察知识:
// 心得体会:
H
solve
模拟即可
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0);
int x, y, k, n, t;
x = read(), y = read(), k = read(), n = read(), t = read();
int res = 0;
int now = x;
int num = 0;
for (int i = n; i >= 1; i--) {
res += i * now;
num += i;
if (res >= t) {
printf("%lld\n", n - i + 1);
return 0;
}
int p = num / k;
now = x + p * y;
// cout << now << endl;
}
// cout << res << endl;
if (res >= t)
printf("%lld\n", n);
else
printf("-1\n");
return 0;
}
// 题目所考察知识:
// 心得体会:
L
solve
完全背包
dp[x]表示剩下x个人时所耗费的最小代价
与完全背包有些许差别,注意循环的顺序
与上一题不同,最后可能到不了0,1,2的最优解
需要从后往前寻找答案
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
const int INF = 0x3f3f3f3f3f3f3f3f;
int b[N], x[N];
int dp[N];
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(0);
int n, m;
n = read(), m = read();
for (int i = 1; i <= m; i++)
b[i] = read(), x[i] = read();
for (int i = 0; i <= n; i++)
dp[i] = INF;
dp[n] = 0;
for (int j = n; j >= 0; j--) {
for (int i = 1; i <= m; i++) {
if (j <= x[i])
continue;
int z = j % x[i];
dp[j - z] = min(dp[j - z], dp[j] + b[i]);
}
}
int res = INF;
for (int i = n; i >= 0; i--) {
if (res > dp[i])
res = dp[i];
else if (dp[i] != INF)
res = dp[i];
}
printf("%lld\n", res);
return 0;
}
// 题目所考察知识:
// 心得体会:
D
solve
用优先队列维护,每次询问进行区间合并即可
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int r1[N];
int l1[N];
int r2[N];
int l2[N];
struct node {
int l, r;
bool operator<(const node p) const { return l > p.l; }
};
priority_queue<node> que1;
priority_queue<node> que2;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
n = read();
int rx = 0, ry = 0;
for (int i = 1; i <= n; i++)
l1[i] = read(), r1[i] = read();
for (int i = 1; i <= n; i++)
l2[i] = read(), r2[i] = read();
for (int i = 1; i <= n; i++) {
node p{l1[i], r1[i]};
node q{l2[i], r2[i]};
que1.push(p);
que2.push(q);
while (!que1.empty()) {
node p1 = que1.top();
if (p1.l <= rx + 1) {
rx = max(rx, p1.r);
que1.pop();
} else
break;
}
while (!que2.empty()) {
node p2 = que2.top();
if (p2.l <= ry + 1) {
ry = max(ry, p2.r);
que2.pop();
} else
break;
}
// cout << rx << " " << ry << endl;
if (rx > ry) {
printf("sa_win!\n");
printf("%lld\n", rx - ry);
} else if (rx < ry) {
printf("ya_win!\n");
printf("%lld\n", ry - rx);
} else {
printf("win_win!\n");
printf("0\n");
}
}
return 0;
}
// 题目所考察知识:
// 心得体会:
C
solve
思维题,考虑细节比较多
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
deque<char> deq1;
deque<char> deq2;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
string s1, s2;
cin >> s1 >> s2;
if (s1.size() == s2.size()) {
if (s1 == s2)
cout << "=" << endl;
else
cout << "!" << endl;
} else {
for (auto s : s1)
deq1.push_back(s);
for (auto s : s2)
deq2.push_back(s);
while (deq1.size() != 0 && deq2.size() != 0 && deq1.back() == deq2.back()) {
deq1.pop_back();
deq2.pop_back();
}
int flag = 0;
int x = deq1.size(), y = deq2.size();
if (deq1.size() < deq2.size()) {
char s = deq2[0];
while (deq2.size() != 0 && deq2.front() == s)
deq2.pop_front();
while (deq1.size() != 0 && deq1.front() == s)
deq1.pop_front();
} else {
char s = deq1[0];
while (deq1.size() != 0 && deq1.front() == s)
deq1.pop_front();
while (deq2.size() != 0 && deq2.front() == s)
deq2.pop_front();
}
if (deq1.size() == deq2.size()) {
cout << "!" << endl;
} else if (deq1.size() < deq2.size()) {
if (x > y)
cout << "!" << endl;
else
cout << "<" << endl;
} else {
if (x < y)
cout << "!" << endl;
else
cout << ">" << endl;
}
}
return 0;
}
// 题目所考察知识:
// 心得体会:
I
solve
结论题,每次放置的灵石最优是当前剩余灵石/2+1
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int res[N];
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
for (int i = n; i >= 2; i--) {
res[i] = m % 2 == 0 ? (m / 2) : (m / 2 + 1);
m -= res[i];
}
res[1] = m;
if(res[1] <= 0){
cout << -1 << endl;
return 0;
}
for (int i = 1; i <= n; i++)
cout << res[i] << " \n"[i == n];
return 0;
}
// 题目所考察知识:
// 心得体会:
F
solve
模拟+思维
对于字符串前面不合乎要求的字符,应该都放置到后面,用stack维护
如果操作完了后k还有剩余,就把末尾的字符纳入考虑
最后排序即可
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
stack<char> stt;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, k;
cin >> n >> k;
string s;
cin >> s;
string ans;
for (int i = 0; i < n; i++) {
while (stt.size() && k) {
if (stt.top() < s[i]) {
ans += stt.top();
stt.pop();
k--;
} else
break;
}
stt.push(s[i]);
}
while (stt.size() && k) {
ans += stt.top();
stt.pop();
k--;
}
sort(ans.begin(), ans.end(), greater<char>());
string temp;
while (stt.size()) {
temp += stt.top();
stt.pop();
}
reverse(temp.begin(), temp.end());
temp += ans;
cout << temp << endl;
return 0;
}
// 题目所考察知识:
// 心得体会: