zoukankan      html  css  js  c++  java
  • Day2T2 分配笔名//CF566A

    首先建一个Trie,考虑贪心选深层节点合并。

    #include<bits/stdc++.h>
    #define fr(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int N=2e6+5;
    int n,p=1;
    int ch[N][26],cnt[N][2];
    long long ans;
    inline void insert(char *a,int v){//普通插入
        int u=1;
        fr(i,0,strlen(a)-1){
            int c=a[i]-'a';
            if(!ch[u][c])ch[u][c]=++p;
            u=ch[u][c];
        }
        ++cnt[u][v];//当前节点结尾的单词+1
    }
    inline void dfs(int u,int dep){
        fr(i,0,25){
            if(ch[u][i])dfs(ch[u][i],dep+1);//递归到深层子节点,让能合并的先合并,得到的就是更优解
            cnt[u][0]+=cnt[ch[u][i]][0];//加上子节点剩余的字符串
            cnt[u][1]+=cnt[ch[u][i]][1];
        }
        int k=min(cnt[u][0],cnt[u][1]);//计算公共部分
        ans+=1ll*k*dep;//累计次数
        cnt[u][0]-=k;cnt[u][1]-=k;//消除已匹配的数量
    }
    char a[N];
    int main(){
        scanf("%d",&n);
        fr(i,1,n)cin>>a,insert(a,0);
        fr(i,1,n)cin>>a,insert(a,1);
        dfs(1,0);
        cout<<ans<<endl;
    }

    如果要求输出方案呢?

    即是CF566A

     考虑用一个Vector来维护每个点结尾的ID,也没什么差吧

    #include<vector>
    #pragma GCC optimize("O2")
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("O3")
    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #define fr(i,a,b) for(register int i=a;i<=b;++i)
    #define rf(i,a,b) for(register int i=a;i>=b;--i)
    using namespace std;
    const int N=1e6+5;
    int n,p=1,pa[N];
    int ch[N][26];
    vector<int> cnt[N][2];
    vector<pair<int,int> > as;
    long long ans;
    inline void dfs(int u,int dep){
        fr(i,0,25){
            int v=ch[u][i];
            if(v){
                dfs(v,dep+1);
                for(register int j=0;j<cnt[v][0].size();++j)cnt[u][0].push_back(cnt[v][0][j]);//记录子节点的id
                for(register int j=0;j<cnt[v][1].size();++j)cnt[u][1].push_back(cnt[v][1][j]);
            }
        }
        ans+=min(cnt[u][0].size(),cnt[u][1].size())*dep;//先把共同的匹配
        for(register int i=min(cnt[u][0].size(),cnt[u][1].size())-1;i>-1;--i){
            as.push_back({cnt[u][0][cnt[u][0].size()-1],cnt[u][1][cnt[u][1].size()-1]});//记录方案
            cnt[u][0].pop_back();cnt[u][1].pop_back();//删除已匹配的数
        }
    }
    string a;
    int main(){
        cin>>n;
        fr(id,1,n){
            cin>>a;
            int u=1;
            for(register int i=0;i<a.size();++i){
             int c=a[i]-'a';
             if(ch[u][c]==0)ch[u][c]=++p;
             u=ch[u][c];
            }
            cnt[u][0].push_back(id);
        }
        fr(id,1,n){
            cin>>a;
            int u=1;
            for(int i=0;i<a.size();++i){
             int c=a[i]-'a';
             if(!ch[u][c])ch[u][c]=++p;
             u=ch[u][c];
            }
            cnt[u][1].push_back(id);//记录
        }
        dfs(1,0);
        printf("%d
    ",ans);
        fr(i,0,n-1)printf("%d %d
    ",as[i].first,as[i].second);
    }

    还有,string和char差这么多,快了N倍

  • 相关阅读:
    Hdu 1094 A+B for Input-Output Practice (VI)
    Hdu 1091 A+B for Input-Output Practice (III)
    Hdu 1092 A+B for Input-Output Practice (IV)
    Hdu 1087 Super Jumping! Jumping! Jumping!
    scala学习笔记2(类,继承,抽象类)
    scala学习笔记1(表达式)
    把以前写的几个Linux Framebuffer小工具放到github上了,直接去下吧,别找我要了
    一位台湾朋友刚建的一个FTK的论坛,欢迎加入讨论
    Linux高端内存的由来
    read系统调用深度剖析
  • 原文地址:https://www.cnblogs.com/coder-cjh/p/11628425.html
Copyright © 2011-2022 走看看