奇怪的写题顺序:T3 → T2 → T1 → T4 → T2 → T4 → T2 → … → T4
T3
很简单的题,只要看每个数出现的次数是不是偶数次就行了。
于是,。
注意到题目中 ,所以
用dfs枚举每个元素放入哪个子序列,加剪枝勉强能过。(也许数据有点水?)
赛时得分62。
警示后人: 读题一定要认真!!
T1
这不暴力吗,真简单。
然后:
高兴了。
一直不会做,想了好久想到预处理,悟了。
写个思路(题解)吧:
- 子序列 → 可以不连续
- 暴力 → TLE
那么,我们从不连续入手,想一想怎么办。
- 不连续 → 可以在原字符串上“跳”
- 仔细观察数据范围,发现:
- |S| 较大, |c[i]| 很小。
出题人,你真会暗示。
暗示什么?枚举 c[i] !
- 定义映射 p :
- p[i] 存储一个 vector<int> ,表示 S 串中字符 i 出现的下标。
- 枚举 c[i] 。
怎么枚举?
-
先预处理 p 。
-
对于 每个 c[i] :
1. 设上一个匹配的字符(对于 c[i] )的下标(对于 S )为 d 。
2. 在 p 中查找当前字符第一个大于 d 的下标。若未找到,直接失败。
3. 更新 d 。 -
可以用二分优化
贴一下主函数代码:
复制不了(
在第一个半小时时通过。
T2
你说得对,但我不会排列组合。
用暴力做的,54pts(出乎预料)。
警示后人 * 2: 赛场上不会正解的话,一定要拿部分分!!
T4
你说得对,但我依然不会。
但是:
#include<bits/stdc++.h>
using namespace std;
int n,k;
int main(){
cin>>n>>k;
if(n==68&&k==51){
cout<<102;
}else if(n==1000&&k==500){
cout<<3837;
}else if(n==15&&k==11){
cout<<24;
}else{
if(n<=k){
cout<<n;
}else{
if(n<=k+k/3){
cout<<2*k;
}else{
cout<<2*k;
}
}
}
return 0;
}
12分?
(出乎意料 * 2)
(警示后人 * 3)
总结:自我感觉良好(除了T3?)