zoukankan      html  css  js  c++  java
  • 2020-11-23至11-30周任务 谔 谔

    写在前面

    此 时 无 声 胜 有 声

    题解

    A

    好水啊,不知道为什么是一道蓝题,感觉顶多绿

    首先,我们发现虽然(n)很大(20000),但是每个字符的长度只有(10),所以,我们可以枚举出每个字符串的连续子集。

    然后开个(map)来存,之后再这题就做完了

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 200000 + 5;
    int n;
    map <string, int> cont; // 记录每一个连续子集出现过的次数
    map <string, int> vis; // 记录是否在当前这个字符串中出现过
    string s[N];
    signed main () {
        ios :: sync_with_stdio (false);
        cin>>n;
        for (int i = 1; i <= n; i++) {
            cin>>s[i];
            vis.clear (); // 清空
            for (int j = 0; j <= s[i].size (); j++) {
                for (int k = 1; j + k <= s[i].size (); k++) {
                    string ss = s[i].substr (j, k);
                     // s.substr(x,y)表示取s[j-j+k]位
                    if (!vis[ss]) {
                        vis[ss] = 1;
                        cont[ss] ++;
                    }
                }
            }
        }
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            ans += cont[s[i]] - 1; // 因为每个人都可以试出自己的密码,所以每个都要减去1
        }
        printf ("%d
    ", ans);
        return 0;
    }
    
    

    B

    C

    D

    E

    一眼题。

    直接tarjan求出连通块,统计连通块最小值并记录就行了

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 1e5 + 5, M = 3e5 + 5, mod = 1e9 + 7;
    struct Node {
        int next, to;
    } edge[M];
    int head[N], cnt;
    inline int read () {
        int tot = 0, f = 1; char c = getchar ();
        while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar (); }
        while (c >= '0' && c <= '9') { tot = tot * 10 + c - '0'; c = getchar (); }
        return tot * f;
    }
    int dfn[N], low[N], deep, tot, color[N];
    bool vis[N];
    int st[N], top;
    int n, m, val[N];
    int minx[N], sum[N];
    inline void add (int x, int y) {
        edge[++cnt].next = head[x];
        edge[cnt].to = y;
        head[x] = cnt;
    }
    inline void tarjan (int u) {
        dfn[u] = low[u] = ++ deep;
        vis[u] = 1; st[++top] = u;
        for (int i = head[u]; i; i = edge[i].next) {
            int v = edge[i].to;
            if (!dfn[v]) {
                tarjan (v);
                low[u] = min (low[u], low[v]);
            }
            else {
                if (vis[v]) low[u] = min (low[u], low[v]);
            }
        }
        if (dfn[u] == low[u]) {
            color[u] = ++tot;
            vis[u] = 0;
            while (st[top] != u) {
                color[st[top]] = tot;
                vis[st[top--]] = 0;
            } top--;
        }
    }
    signed main () {
        n = read ();
        for (int i = 1; i <= n; i++) val[i] = read (); m = read ();
        for (int i = 1; i <= m; i++) {
            int x = read (), y = read ();
            add (x, y);
        }
        for (int i = 1; i <= n; i++)
            if (!dfn[i]) tarjan (i);
        // for (int i = 1; i <= n; i++) cout<<color[i]<<" "; cout<<endl;
        memset (minx, 0x3f, sizeof (minx));
        for (int i = 1; i <= n; i++) {
            if (val[i] < minx[color[i]]) minx[color[i]] = val[i], sum[color[i]] = 1;
            else if (val[i] == minx[color[i]]) sum[color[i]]++;
        }
        // cout<<sum[1]<<endl;
        long long ans = minx[1], rans = sum[1];
        for (int i = 2; i <= tot; i++) {
            ans += minx[i];
            rans *= sum[i]; rans %= mod;
        }
        printf ("%lld %lld
    ", ans, rans);
        return 0;
    }
    
    

    F

    Link

    我们可以将同一颜色的连通块缩成点。

    然后我们就得到了一棵黑白相间的树。

    树的直径的一半即为答案

    ps:树的直径,先从随便一个点出发找到最远的点,再从最远的点走到这个点的最远的点,即为树的直径

    #include <bits/stdc++.h>
    using namespace std ;
    const int MAXN = 200000 + 5 ;
    int color[ MAXN ] , fa[ MAXN ] , n ;
    struct Node {
        int next , to , w ;
    } edge[ MAXN << 1 ] ;
    int head[ MAXN ] , cnt ;
    inline int read () {
        int tot = 0 , f = 1 ; char c = getchar () ;
        while ( c < '0' || c > '9' ) { if ( c == '-' ) f = -1 ; c = getchar () ; }
        while ( c >= '0' && c <= '9' ) { tot = tot * 10 + c - '0' ; c = getchar () ; }
        return tot * f ;
    }
    inline void add ( int x , int y ) {
        edge[ ++ cnt ].next = head[ x ] ;
        edge[ cnt ].to = y ;
        head[ x ] = cnt ;
    }
    inline int find ( int k ) {
        if ( fa[ k ] == k ) return k ;
        else return fa[ k ] = find ( fa[ k ] ) ;
    }
    int maxdeep , maxu ;
    inline void dfs ( int deep , int u , int father ) {
        if ( deep > maxdeep ) maxdeep = deep , maxu = u ;
        for ( int i = head[ u ] ; i ; i = edge[ i ].next ) {
            int v = edge[ i ].to ;
            if ( v == father ) continue ;
            dfs ( deep + 1 , v , u ) ;
        }
    }
    int a[ MAXN ] , b[ MAXN ] ;
    signed main () {
        n = read () ;
        for ( int i = 1 ; i <= n ; i ++ ) {
            color[ i ] = read () ;
            fa[ i ] = i ;
        }
        for ( int i = 1 ; i < n ; i ++ ) {
            a[ i ] = read () ; b[ i ] = read () ;
            int fx = find ( a[ i ] ) , fy = find ( b[ i ] ) ;
            if ( color[ fx ] == color[ fy ] ) fa[ fx ] = fa[ fy ] ;
        }
        for ( int i = 1 ; i <= n ; i ++ )
            fa[ i ] = find ( fa[ i ] ) ;
        for ( int i = 1 ; i <= n ; i ++ )
            if ( fa[ a[ i ] ] != fa[ b[ i ] ] )
                add ( fa[ a[ i ] ] , fa[ b[ i ] ] ) , add ( fa[ b[ i ] ] , fa[ a[ i ] ] ) ;
        dfs ( 0 , fa[ 1 ] , 0 ) ;
        dfs ( 0 , maxu , 0 ) ;
        printf ( "%d
    " , ( maxdeep + 1 ) / 2 ) ;
    }
    
  • 相关阅读:
    jquery操作cookie
    javascript数组(五)
    javascript var变量删除
    javascript 语句和严格模式(三)
    javascript 表达式和运算符 (二)
    javascript类型判断
    javascript 六种数据类型(一)
    计算机网络之网络排查(四)
    计算机网络封装解封装(三)
    计算机网络—从输入网址到显示网页的过程(二)
  • 原文地址:https://www.cnblogs.com/hulean/p/14030615.html
Copyright © 2011-2022 走看看