Codeforces Round #476 (Div. 2) 题解
Codeforces Round #476 (Div. 2) 题解
A
喵~
B
喵~
emm..总之别想多了,直接枚举就好。
C
喵~
啊喂!打住!这题不能喵了。
枚举1号位收到糖果的次数D
,然后我们可以求出max_x
。max_x * D
即为答案
二分保平安!
D
做法:
rd(l); rd(w);
rep(i,1,l-1) {
rd(a[i]),a[i]+=a[i-1];
}
LL mn=1e9+7;
rep(i,w,l-1) mn=min(mn,a[i]-a[i-w]);
cout<<mn<<endl;
最大流=最小割=min 长度为L的连续段中石头个数
E
卡成智障....
比赛时也想到了把深度最深的点拿上来。然而我很坚决地认为这是个假算法。
做法:问题可以转化成Trie树上有很多只排骨龙,排骨龙可以往根爬,但两只排骨龙不能站在同一个节点上,现在想让排骨龙深度之和最小。
如果u节点的子树都施展好了,现在我们更新u节点。两种情况
- u节点有排骨龙,那么把所有儿子相加就好。
- u节点没有排骨龙,那把深度最深的排骨龙拎上来。
用堆维护每个节点子树中最优解排骨龙的深度信息。然后合并的时候小的往大的上合并。
const int N=100000+10;
const double EPS = 1e-8;
char s[N];
int n,ch[N][30],dep[N],has[N],size;
multiset<LL> st[N];
void insert(char * s) {
int now=0;
for(int i=0;s[i];i++) {
int c=s[i]-'a';
if(ch[now][c] == 0) {
ch[now][c] = ++size;
}
dep[ch[now][c]]=dep[now]+1;
now = ch[now][c];
}
st[now].insert(dep[now]);
has[now]=1;
}
void dfs(int u) {
rep(i,0,25){
int v=ch[u][i];
if(v==0) continue;
dfs(v);
if(st[u].size() < st[v].size())
swap(st[u],st[v]);
for(auto x:st[v])
st[u].insert(x);
}
if (st[u].size() && has[u]==0) {
st[u].erase(st[u].find(*st[u].rbegin()));
st[u].insert(dep[u]);
}
}
int main(){
rd(n);
rep(i,1,n){
scanf("%s",s);
insert(s);
}
has[0]=1; dfs(0);
LL ret=0;
for(auto x:st[0]) {
ret += x;
//printf("%d\n", x);
}
cout<<ret<<endl;
}
总结
- A 5min, 1Y
- B 21min, 1Y
- C 94min, WA*3
- D 66min, 1Y
- E GG
B题,直接暴力枚举就好了,别!玩!杂!技!
C题,第一下没施展开,然后整个人方了,开始乱搞一气,乱加特判什么的。
D题,不错的直感!几乎秒杀。
E题,有种整个人沉入海底的那种感觉,不知道该干什么,不知道能干什么,在犹豫中,整个人就被水淹没了。其实还是实现算法的意识不够好吧,想法什么的仅仅只是存在于那么一瞬间而已,然后就随风飘散了。emmmmmm.....试着去捕捉一下转瞬即逝的想法吧。