2020浙江省赛ZJCPC C.Crossword Validation

原题链接

题意很长,直接看输出和输出,大概意思就是给你m个单词,每个单词都有不同的权值,问矩阵中的所有最长单词是否都在这m个单词中,如果在就累加权值,不在就输出-1。

关于矩阵中单词的取法,从左到右取直到“#”停止,从上往下取直到”#“停止。

解法很简单,只要根据m个单词建一棵字典树,再遍历矩阵去找,时间复杂度只要n^2。

记得初始化时别memset全部的trie,只要初始化用到的即可。

#include <bits/stdc++.h>
using namespace std;
//#define ACM_LOCAL
typedef long long ll;
const int N = 4e6 + 10;
const int MOD = 1e9 + 7;
char mp[1005][1005];
int cnt, level[N], trie[N][26];

void insert(char *s, int v) {
    
    
    int now = 0, len = strlen(s);
    for (int i = 0; i < len; i++) {
    
    
        int temp = s[i] - 'a';
        if (!trie[now][temp]) trie[now][temp] = ++cnt;
        now = trie[now][temp];
    }
    level[now] += v;
}

ll query(char *s) {
    
    
    int now = 0, len = strlen(s);
    for (int i = 0; i < len; i++) {
    
    
        now = trie[now][s[i] - 'a'];
        if (!now) return -1;
    }
    if (!level[now]) return -1;
    else return level[now];
}

int T, n, m;
char temp[1005];

void solve() {
    
    
    scanf("%d", &T);
    while (T--) {
    
    
        for (int i = 0; i <= cnt; i++)
            memset(trie[i], 0, sizeof trie[i]), level[i] = 0;
        cnt = 0;
//------------------------------------------------------初始化
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; i++)
            scanf("%s", mp[i] + 1);

//------------------------------------------------------ 输入

        int v;
        for (int i = 1; i <= m; i++) {
    
    
            scanf("%s %d", temp, &v);
            insert(temp, v);
        }
//------------------------------------------------------建树
        ll ans = 0;
        int f = 0;

        for (int i = 1; i <= n; i++) {
    
    
            for (int j = 1; j <= n; j++) {
    
    
                int k = 0;
                if (mp[i][j] == '#') continue;
                while (mp[i][j] != '#' && j <= n) temp[k++] = mp[i][j++];
                temp[k] = 0;
                int val = query(temp);
                if (val == -1) f = 1;
                else ans += val;
            }
        }

        for (int j = 1; j <= n; j++) {
    
    
            for (int i = 1; i <= n; i++) {
    
    
                int k = 0;
                if (mp[i][j] == '#') continue;
                while (mp[i][j] != '#' && i <= n) temp[k++] = mp[i++][j];
                temp[k] = 0;
                int val = query(temp);
                if (val == -1) f = 1;
                else ans += val;
            }
        }

        if (f) printf("-1\n");
        else printf("%lld\n", ans);
    }
//------------------------------------------------------查询
}

signed main() {
    
    
    cin.tie(0);
    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("input", "r", stdin);
    freopen("output", "w", stdout);
#endif
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/kaka03200/article/details/109382959