B班集训8月23日模拟赛补题日志

前缀串(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 1i<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;
}

总结:打的不好,还要努力。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值