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题还看题题意导致花了好长时间= =不过无所谓,反正我做的是虚拟竞赛

原文地址:https://www.cnblogs.com/scaugsh/p/6380441.html