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

    B. Petya and Exam

    题意:

    给你一个定义为好的字符集合和一个字符串s进行字符匹配。字符s为小写字母、‘*’和‘?’组成。其中‘?’可以任意替换一个好的字符,‘*’可以替换一个由坏的字符组成的串或者去掉‘*’,‘*’最多出现一次。然后给出n个字符串是否匹配。

    思路:

    直接模拟,要是‘?’就要检查字符是否是为好的字符。要是‘*’就break进行去掉和串的替换两次操作,检查是否成功匹配。

    #include <bits/stdc++.h>
    using namespace std;
    #define LOCAL
    typedef long long LL;
    typedef pair<int, int> PAI;
    const int INF = 0x3f3f3f3f;
    const double ESP = 1e-5;
    const double PI = acos(-1.0);
    const int MOD = 1e9 + 7;
    const int MAXN = 1e5 + 100;
    char s[MAXN], good[MAXN], qs[MAXN];
    bool vis[MAXN];
    int main(int argc, char const *argv[])
    {
        scanf("%s", good);
        memset(vis, false, sizeof(vis));
        int le = strlen(good);
        for (int i = 0; i < le; i++) {
            int t = good[i] - 'a';
            vis[t] = true;        
        }
        scanf("%s", s);
        int lens = strlen(s);
        int q;
        scanf("%d", &q);
        while (q--) {
            scanf("%s", qs);
            int lenq = strlen(qs);
            int i, j;
            bool flag = true;
            bool star = false;
            for (i = 0, j = 0; i < lenq; i++, j++) {
                if (s[j] == qs[i]) continue;
                else if (s[j] == '?' && vis[qs[i] - 'a']) continue;
                else if (s[j] == '*') {star = true; break;}
                else flag = false;
                if (!flag) break;
            }
            bool flag1 = true, flag2 = true;
            if (star) {
                int i1 = i, j1 = ++j;
                for (;i1 < lenq; i1++, j1++) {
                    if (s[j1] == qs[i1]) continue;
                    else if (s[j1] == '?' && vis[qs[i1] - 'a']) continue;
                    else flag1 = false;
                    if (!flag1) break;
                }
                int i2 = i, j2 = j, t;
                for (t = 0; t <= lenq - lens; t++) if (vis[qs[i2 + t] - 'a']) {flag2 = false; break;}
                if (flag2) {
                    i2 += t;
                    for (; i2 < lenq; i2++, j2++) {
                        if (s[j2] == qs[i2]) continue;
                        else if (s[j2] == '?' && vis[qs[i2] - 'a']) continue;
                        else flag2 = false;
                        if (!flag2) break;
                    }
                }
                flag = (flag1 and (lenq + 1 == lens)) or (flag2 and (lenq >= lens));
            }
            if (!star && (lens - lenq > 1 || (lens - lenq == 1 && s[i] != '*'))) flag = false;
            if (flag) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    View Code

    D. Misha, Grisha and Underground

    题意:

    给你一颗树,每次询问三个节点,任选一个当做终点其他两个为起始点,求两条路径相交的最大值。

    思路:

    LCA,求出三个相交路径的最大值。(d(a,b) + d(c,b) - d(a,c)) /2 为从a,c出发,到b的相交距离。

    #include "bits/stdc++.h"
    using namespace std;
    const int maxn = 200100;
    struct edge {
        int to, next;
    }e[2*maxn];
    int dp[maxn][30], dis[maxn];
    bool vis[maxn];
    int fa[maxn], d[maxn*2], head[maxn];
    int cnt, num, first[maxn], ver[maxn*2];
    void add(int u, int v) {
        e[num].to = v; 
        e[num].next = head[u]; head[u] = num++;
    }
    void dfs(int u, int dep) {
        vis[u] = true; ver[++cnt] = u; first[u] = cnt; d[cnt] = dep;
        for (int i = head[u]; i != -1; i = e[i].next) {
            int v = e[i].to;
            if (!vis[v]) {
                dis[v] = dis[u] + 1;
                dfs(e[i].to, dep + 1);
                ver[++cnt] = u; d[cnt] = dep;
            }
        }
    }
    void ST(int n) {
        for (int i = 1; i <= n; i++) dp[i][0] = i;
        for (int j = 1; (1<<j) <= n; j++) {
            for(int i = 1; i+(1<<j)-1 <= n; i++) {
                int a = dp[i][j-1], b = dp[i+(1<<(j-1))][j-1];  
                dp[i][j] = d[a] < d[b]?a:b;  
            }  
        }
    }
    int RMQ(int l, int r) {
        int k=0;  
        while((1<<(k+1)) <= r-l+1) k++;  
        int a = dp[l][k], b = dp[r-(1<<k)+1][k];   
        return d[a]<d[b]? a: b;  
    }
    int LCA(int u ,int v) {
        int x = first[u] , y = first[v];  
        if(x > y) swap(x, y);  
        int res = RMQ(x, y);  
        return ver[res];  
    } 
    int dist(int x, int y) {
        int u = LCA(x, y);
        return dis[x] + dis[y] - 2*dis[u];
    }
    int main(int argc, char const *argv[]) {
        int n, q;
        memset(vis, false, sizeof(vis));
        memset(head, -1, sizeof(head));
        scanf("%d%d", &n, &q);
        num = 0;
        for (int u = 2; u <= n; u++) {
            int v;
            scanf("%d", &v);
            add(u, v); add(v, u);
        }
        cnt = 0; d[1] = 0; 
        dfs(1,1);
        ST(2*n-1);
        while (q--) {
            int a, b, c, lab, lbc, lac;
            cin >> a >> b >> c;
            lab = dist(a, b);
            lbc = dist(b, c);
            lac = dist(a, c);
            int s1 = (lab+lac - lbc)/2+1;
            int s2 = (lab+lbc - lac)/2+1;
            int s3 = (lac+lbc - lab)/2+1;
            int ans = max(s1, max(s2, s3));
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    POJ 3672 水题......
    POJ 3279 枚举?
    STL
    241. Different Ways to Add Parentheses
    282. Expression Add Operators
    169. Majority Element
    Weekly Contest 121
    927. Three Equal Parts
    910. Smallest Range II
    921. Minimum Add to Make Parentheses Valid
  • 原文地址:https://www.cnblogs.com/cniwoq/p/7238624.html
Copyright © 2011-2022 走看看