Codeforces Round #476 (Div. 2) 题解

Codeforces Round #476 (Div. 2) 题解

A

喵~

B

喵~

emm..总之别想多了,直接枚举就好。

C

喵~

啊喂!打住!这题不能喵了。

枚举1号位收到糖果的次数D,然后我们可以求出max_xmax_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.....试着去捕捉一下转瞬即逝的想法吧。

posted @ 2018-05-08 16:23  RUSH_D_CAT  阅读(135)  评论(0编辑  收藏  举报