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\n");
        else printf("NO\n");
    }
    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\n", ans);
    }
    return 0;
}
View Code

 

posted @ 2017-07-26 11:20  zprhhs  阅读(153)  评论(0编辑  收藏  举报
Power by awescnb