ABC 315 题解

ABC315 总结 & 题解

Contest Overview

题目质量较高,特别是 F。

建议 D 和 E 对调。

A

Overview

字符串操作题。

Description

给定字符串 s s s,输出删去所有元音字母后的字符串。

Idea

设立一个空字符串 t t t,暴力插入即可。

Solution

部分代码,全部代码见附件。

if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u'){
	continue;
}
t = t + s[i];

B

Overview

边界判断可能造成罚时,需注意。

Description

给定 n n n 个月的日历,第 i i i 个月有 t i t_i ti 天(保证总天数为奇),问中间的那一天是几月几号。

Idea

先求出一年有几天, + 1 ÷ 2 +1\div 2 +1÷2,暴力求就可以了。

注意:一月的最后一天不是第二月的第 0 0 0 天。

Solution

部分代码,全部代码见附件。

arrin<int>(d, d + n);
int sum = 0; 
repn(i, 0, n, 1) sum += d[i];
sum = (sum + 1) / 2; 
int pos = 0;
while(sum - d[pos] > 0){
	sum -= d[pos]; pos++;
}
cout << pos + 1 << " " << sum << endl;

C

Overview

套路题,其实没有套路也是可做的。

Description

给定 n n n 个数对,每个数对都有 种类 a a a 和 价值 b b b

定义一对数对的「价值」是:

  • b i + b j b_i+b_j bi+bj i ≠ j i\ne j i=j
  • b i + b j 2 b_i+\frac{b_j}2 bi+2bj i = j i=j i=j

求出最大价值。

n ≤ 2 × 1 0 5 n \leq 2\times10^5 n2×105

Idea

第二种情况相当好求,这里着重讲第一种情况。

显然,对于每个种类 i i i,最大价值有 这个种类的最大价值 + 其它种类的最大价值。

思考:如何求第二个项?

显然是可以通过拆环 + 线段树做的,但是毕竟是 C,不会这么难。

考虑预处理前缀最大值 p p p,后缀最大值 s s s

所以答案 = max ⁡ { p i − 1 , s i + 1 } \max\{p_{i-1},s_{i+1}\} max{pi1,si+1}

Solution

部分代码,全部代码见附件。

cn(n); pii p[n];
repn(i, 0, n, 1){
	cm(p[i].first); cm(p[i].second);
}
repn(i, 0, n, 1){
	if(p[i].second > mx[p[i].first])
		mx2[p[i].first] = mx[p[i].first], mx[p[i].first] = p[i].second;
	else if(p[i].second > mx2[p[i].first])
		mx2[p[i].first] = p[i].second;
}
mmx[1] = mx[1], mmx2[n] = mx[n];
rep(i, 2, n, 1)
	mmx[i] = max(mmx[i - 1], mx[i]);
pre(i, n - 1, 1, 1)
	mmx2[i] = max(mmx2[i + 1], mx[i]);
int maxv = 0;
rep(i, 1, n, 1){
	maxv = max(maxv, max(mx[i] + mx2[i] / 2, mx[i] + max(mmx[i - 1], mmx2[i + 1])));
}
cout << maxv << endl;

D

Overview

中规中矩的一道题,但有些奇怪。

Description

给定一个 h × w h\times w h×w 的矩阵,求不断删去每一个有相同元素的行和有相同元素的列后剩下的个数。

注意:行和列是同时进行的。

h , w ≤ 1000 h,w\leq 1000 h,w1000

Idea

因为本人太菜而先做了 E 和 F,此题只有口胡解法,不保证正确性,欢迎 fake。

考虑到只有 1 0 6 10^6 106 个数,每个数只会被删一次,可以暴力删除。

对于每个行、列维护一个桶和一个 set

理论最坏复杂度大约是 O ( 52 n 2 log ⁡ n ) O(52n^2 \log n) O(52n2logn),但是远远跑不到。可能会卡过去。

E

Overview

板子题。

Description

给定 n n n 个物品和其依赖关系,给出一个能够到达 1 1 1 的排列方式,需要保证选择个数最少。

保证依赖关系组成的图是一个 DAG。

Idea

赤裸裸的板子题。

按照依赖关系建图,拓扑排序就可以了。

怎么保证所用个数最少?

建反向边。DFS 一遍,找到必须选择的点。

Solution

见附件。

F

Overview

好题。较为结论。

Description

给定 n n n 个二维平面上的点。你需要从 1 1 1 一直按顺序跳到 n n n

你可以选择跳过若干个点。设你跳过了 k k k 个点( 1 1 1 n n n 除外),走过的总距离为 x x x

则你的「罚时」是 x + 2 k − 1 x+2^{k-1} x+2k1。特别的,我们设 2 − 1 = 0 2^{-1}=0 21=0

n , x i , y i ≤ 1 0 4 n,x_i,y_i \leq 10^4 n,xi,yi104,其中 x i x_i xi y i y_i yi 为一个点的坐标。

Idea

注意到总距离最大大约是 1 0 8 10^8 108,所以 k k k 一定 ≤ log ⁡ 1 0 8 \leq \log 10^8 log108,不然什么也不选就是更优解。

所以只用枚举 1 1 1 35 35 35 k k k 就可以了(为了防止爆炸我将 k k k 开大了一点)。

剩下的 DP 一下就可以了。

d i , j d_{i,j} di,j 为前 i i i 个点跳了 j j j 个点的最小距离。

状态转移方程自己推去!(恼

Solution

部分代码,全部代码见附件。

rep(i, 0, 35, 1){
	repn(j, 0, n, 1) rep(k, 0, i, 1){
		dp[j][k] = MAXN;
	}
	dp[0][0] = 0;
	repn(j, 1, n, 1) rep(k, 0, i, 1){
		rep(l, 0, k, 1){
			if(j - l - 1 < 0) break;
			dp[j][k] = min(dp[j][k], dp[j - l - 1][k - l] + dist(p[j], p[j - l - 1]));
		}
	}
	ans = min(ans, dp[n - 1][i] + (i == 0 ? 0LL : (1LL << (i - 1LL))));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值