前缀串(string)
题意:给你 n n n 个字符串,输出字典序最小的前缀为 S S S 的字符串。
未通过原因:把 “前缀” 理解错误。
解题思路:每个字符串都判断是否满足要求,然后输出字典序最大的那个。
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
string S, k, t, ans = "";
int n;
cin >> S >> n;
while (n--) {
cin >> k;
if (k.substr(0, S.size()) == S && (k < ans || ans == "")) ans = k; // 判断是否合法
}
cout << ans << endl;
return 0;
}
放椅子(chair)
题意:现在有 n n n 个人,每个人左边放 L i L_i Li 张椅子,右边要放 R i R_i Ri 张椅子,求最少放几张椅子。
未通过原因:没有开 long long
。
解题思路:把 L I L_I LI 和 R i R_i Ri 都排序一遍。在遍历其排序后每一个 i i i 取 max ( L i , R i ) \max(L_i,R_i) max(Li,Ri),将他们累加起来。
代码:
#include <bits/stdc++.h>
using namespace std;
long long n, l[100005], r[100005], ans;
int main() {
cin >> n;
for (long long i = 1; i <= n; i++) cin >> l[i] >> r[i];
sort(l + 1, l + n + 1); // 排序
sort(r + 1, r + n + 1);
for (long long i = 1; i <= n; i++) ans += max(l[i], r[i]); // 累加结果
cout << ans + n << endl;
return 0;
}
天天爱消除(erase)
题意:有 n n n 个排成一行的球, 每次选择相邻的 1 1 1~ 3 3 3 个颜色相同的信号球进行消除,分别得到 a , b , c a,b,c a,b,c 的分数。一个球在消除后,其两边的球会连在一起。求最大能得多少分。
未通过原因:区间 DP 写错了 。
解题思路:区间 DP 一遍。
代码:
#include <bits/stdc++.h>
using namespace std;
int n, a, b, c, s[305], dp[305][305];
int main() {
cin >> n >> a >> b >> c;
for (int i = 1; i <= n; i++) cin >> s[i];
for (int len = 1; len <= n; len++) { // 枚举长度
for (int l = 1, r = len; r <= n; l++, r++) { // 枚举区间
if (len == 1) { // 单消
dp[l][r] = a;
continue;
}
if (s[l] == s[r]) dp[l][r] = dp[l + 1][r - 1] + b; // 双消
for (int k = l; k < r; k++) { // 枚举断点
dp[l][r] = max(dp[l][r], dp[l][k] + dp[k + 1][r]);
}
for (int k = l + 1; k < r; k++) { // 三消
if (s[l] == s[k] && s[k] == s[r]) dp[l][r] = max(dp[l][r], dp[l + 1][k - 1] + dp[k + 1][r - 1] + c);
}
}
}
cout << dp[1][n] << endl;
return 0;
}
四元组计数(count)
题意:给你一个长度为 n n n 的数组 a i a_i ai,求满足 1 ≤ i < j < p < q 1\le i<j<p<q 1≤i<j<p<q 且 a i < a p < a j < a q a_i<a_p<a_j<a_q ai<ap<aj<aq 的四元组 ( i , j , p , q ) (i,j,p,q) (i,j,p,q) 的数量。
未通过原因:我不会 。
解题思路:处理一个 “前缀和” 和 “后缀和” 统计满足 a i < a p a_i<a_p ai<ap 和 a j < a q a_j<a_q aj<aq 的数量,再枚举 j , p j,p j,p 即可。
代码:
#include <bits/stdc++.h>
using namespace std;
int n, a[5005], pre[5005][5005], suf[5005][5005];
long long ans;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) { // 处理前缀
for (int j = 1; j <= n; j++) pre[i][j] = pre[i][j - 1] + (a[j] < a[i]);
}
for (int i = 1; i <= n; i++) { // 处理后缀
for (int j = n; j >= 1; j--) suf[i][j] = suf[i][j + 1] + (a[j] > a[i]);
}
for (int j = 2; j + 2 <= n; j++) {
for (int p = j + 1; p + 1 <= n; p++) { // 累加结果
if (a[j] > a[p]) ans += (long long)pre[p][j - 1] * (long long)suf[j][p + 1];
}
}
cout << ans << endl;
return 0;
}
总结:打的不好,还要努力。。