zoukankan      html  css  js  c++  java
  • Codeforces Round #396 (Div. 2)

    传送门:http://codeforces.com/contest/766

    A题:给你两个字符串,求两个字符串的最大非公共子串长度。假设

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <bitset>
    #define X first
    #define Y second
    #define clr(u,v); memset(u,v,sizeof(u));
    #define in() freopen("data","r",stdin);
    #define out() freopen("ans","w",stdout);
    #define Clear(Q); while (!Q.empty()) Q.pop();
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int maxn = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    
    int main()
    {
        string s1, s2;
        cin >> s1 >> s2;
        if (s1 == s2) cout << -1 << endl;
        else cout << max(s1.length(), s2.length()) << endl;
        return 0;
    }
    View Code

    B题:给你n条线段,问能不能找到三条线段组成一个三角形。考虑三条边a,b,c有a<=b=<c,只要保证a+b>c>b-a就行了,事实上只要保证a+b>c就可以,假设c<=b-a,则a+c<=b<c,=>a<0矛盾,所以只要保证a+b>c就好,那a+b要尽可能大,所以肯定是恰好小于等于c的两个线段,所以直接对线段进行排序,扫一遍找到有N[i]<N[i-1]+N[i-2]的线段就行了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <bitset>
    #define X first
    #define Y second
    #define clr(u,v); memset(u,v,sizeof(u));
    #define in() freopen("data","r",stdin);
    #define out() freopen("ans","w",stdout);
    #define Clear(Q); while (!Q.empty()) Q.pop();
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int maxn = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    int N[maxn];
    int main()
    {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            scanf("%d", &N[i]);
        sort(N, N + n);
        for (int i = 2; i < n; i++)
        {
            if (N[i] < N[i-1] + N[i-2])
            {
                puts("YES");
                return 0;
            }
        }
        puts("NO");
        return 0;
    }
    View Code

    C题:给你一个长度为n的字符串str,以及数组a,ax表示字符x只能出现在长度为ax以内的字符串里,现在要求对字符串进行合法分隔,问有多少种分隔方法,并输出分隔出的字符串最长长度,以及分隔最少个数。这题直接xjb dp做的,dp[i]表示以i作为分界点的方案数,那么我们找下标小于i的,满足Minax<len的位置加起来,就是dp[i]了,具体还是看代码吧。至于最长长度和最少个数在dp的时候顺便更新一下就好了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <bitset>
    #define X first
    #define Y second
    #define clr(u,v); memset(u,v,sizeof(u));
    #define in() freopen("data","r",stdin);
    #define out() freopen("ans","w",stdout);
    #define Clear(Q); while (!Q.empty()) Q.pop();
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int maxn = 1e3 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    int dp[maxn];
    int c[30];
    char str[maxn];
    int Mincnt[maxn];
    int main()
    {
        clr(Mincnt, 0x3f);
        int n;
        scanf("%d", &n);
        scanf("%s", str + 1);
        for (int i = 0; i < 26; i++) scanf("%d", &c[i]);
        dp[0] = 1;
        Mincnt[0] = 0;
        int Maxlen = 0;
        for (int i = 1; i <= n; i++)
        {
            int Min = c[str[i] - 'a'], len = 1;
            for (int j = i - 1; j >= 0; j--)
            {
                len++;
                Min = min(Min, c[str[j] - 'a']);
                dp[i] = (dp[j] + dp[i]) % mod;
                Mincnt[i] = min(Mincnt[i], Mincnt[j] + 1);
                if (Min < len) break;
            }
            Maxlen = max(Maxlen, len - 1);
        }
    //    for (int i=0;i<=n;i++) cout<<dp[i]<<endl;
        cout << dp[n] << endl;
        cout << Maxlen << endl;
        cout << Mincnt[n] << endl;
        return 0;
    }
    View Code

    D题:给你n个单词,并给出m组操作,把单词归为同类和不同类,注意不同类的不同类就是同一类。再有q组查询,查询单词之间的关系。这题和之前做过的一题很类似,其实就是个并查集,具体查看:http://www.cnblogs.com/scaugsh/p/5533202.html 跟这题差不多,就是把id和id+n当作不同关系后直接并查集就行了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <bitset>
    #define X first
    #define Y second
    #define clr(u,v); memset(u,v,sizeof(u));
    #define in() freopen("data","r",stdin);
    #define out() freopen("ans","w",stdout);
    #define Clear(Q); while (!Q.empty()) Q.pop();
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int maxn = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    int n, m, q, t;
    int f[maxn];
    void init()
    {
        for (int i = 0; i <= 2 * n; i++) f[i] = i;
    }
    int find(int x)
    {
        return f[x] == x ? x : f[x] = find(f[x]);
    }
    void mix(int x, int y)
    {
        int fx = find(x), fy = find(y);
        f[fx] = fy;
    }
    
    map <string, int> M;
    
    int main()
    {
        //ios::sync_with_stdio(false);
        cin >> n >> m >> q;
        init();
        int cnt = 0;
        for (int i = 0; i < n; i++)
        {
            string str;
            cin >> str;
            M[str] = cnt++;
        }
        while (m--)
        {
            cin >> t;
            string str1, str2;
            cin >> str1 >> str2;
            if (t == 1)
            {
                int id1 = M[str1], id2 = M[str2];
                if (find(id1) == find(id2 + n) || find(id1 + n) == find(id2))
                {
                    cout << "NO" << endl;
                    continue;
                }
                cout << "YES" << endl;
                mix(id1, id2), mix(id1 + n, id2 + n);
            }
            else
            {
                int id1 = M[str1], id2 = M[str2];
                if (find(id1) == find(id2) || find(id1 + n) == find(id2 + n))
                {
                    cout << "NO" << endl;
                    continue;
                }
                cout << "YES" << endl;
                mix(id1 + n, id2), mix(id1, id2 + n);
            }
        }
        while (q--)
        {
            string str1, str2;
            cin >> str1 >> str2;
            int id1 = M[str1], id2 = M[str2];
            if (find(id1) == find(id2) || find(id1 + n) == find(id2 + n)) cout << 1 << endl;
            else if (find(id1) == find(id2 + n) || find(id1 + n) == find(id2)) cout << 2 << endl;
            else cout << 3 << endl;
        }
        return 0;
    }
    View Code

    这场四题还不算难,不过ab题题意理解难度增加了,b题还看题题意导致花了好长时间= =不过无所谓,反正我做的是虚拟竞赛

  • 相关阅读:
    Juniper路由器
    Juniper交换机维护
    [转载]让你瞬间开悟的图片
    [转载]生命科学-人体生物磁场及特异作用
    NAS与SAN有什么区别?
    使用串口终端安装AIX操作系统
    xml与java代码相互装换的工具类
    mybatis思维导图(二)
    mybatis思维导图(一)
    Spring思维导图(AOP篇)
  • 原文地址:https://www.cnblogs.com/scaugsh/p/6380441.html
Copyright © 2011-2022 走看看