10.13校内二试

10.13校内二试


QwQ只有爆零的我发出反狱的绝叫

其实250 pts

T1 CPU任务执行

大模拟QwQ

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int MAXN = 100010;
struct PROC{
    int time;
    string id;
    PROC(string x = "", int y = 0) {time = y; id = x;}
};
int n, ti, q, now;
string na;
std::queue<PROC> que;
int main() {
    ios::sync_with_stdio(false);
    cin >> n >> q;
    for (int i = 1; i <= n; ++i) {
        cin >> na >> ti;
        que.push(PROC(na, ti));
    }
    while(!que.empty()) {
        na = que.front().id; ti = que.front().time; que.pop();
        if(ti <= q) {
            now += ti; cout << na << ' ' << now << '\n';
        } 
        else {
            now += q; ti -= q; que.push(PROC(na, ti));
        }
    }
    return 0;
}

T2 单词统计

原题 前缀单词

考场上花了一个小时写T1和T3,然后剩下三个小时都在搞T2。

写了一个正确性完全没有的DP,然后竟然得了50 pts。赛后找题解,发现sort一下就可以过。求解答。

然而其实是在Trie树上递推一下。

考虑先建Trie。树上有直系关系的点不可以同时选。设\(f[i]\)为当前点及其子树的方案数(当然子树之间是可以随便选的嘛)。所以\(f[i]\)初值为1,\(f[i] = f[i] * \prod\limits_{j \in subtree} f[j]\)。在最后别忘了当前点若为字符结尾的话,方案数要加1。

在Trie上跑好像会多跑一点路,但是对正确性没有影响。

#include <cstdio>
#include <vector>
typedef long long ll;
const int MAXL = 2510;
int n, top;
char ss[60][60];
bool map[60][60];
ll ans, f[MAXL];
struct TRIE{
    int a[26], exist;
}trie[MAXL];
inline void insert(char* str) {
    int iter(0), tmp(0), now(0);
    for (; str[iter]; ++iter) {
        if(!trie[now].a[(tmp = str[iter] - 'a')]) trie[now].a[tmp] = ++top;
        now = trie[now].a[tmp];
    }
    trie[now].exist = true;
    return ;
}
inline void dfs(int now) {
    f[now] = 1;
    for (int i = 0; i < 26; ++i) {
        if(!trie[now].a[i]) continue;
        dfs(trie[now].a[i]);
        f[now] *= f[trie[now].a[i]];
    }
    f[now] += trie[now].exist;
    return ;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%s", ss[i]), insert(ss[i]), f[i] = 1;
    dfs(0);
    printf("%lld\n", f[0]);
    return 0;
}

T3 道路修建

原题 道路修建

考虑先以某个点(任意点)为根跑dfs,记录子树大小\(size\)和它的深度\(dep\)

存边,对每条边统计答案。设u为边两端点中较浅的,v为较深的一点。这时\(n~-~size[v]\)为u一侧的城市个数,\(size[v]\)为v一侧的城市个数,统计\(ans += abs(n - size[v] - size[v]) * w\)即可。

#include <algorithm>
#include <cctype>
#include <cstdio>
typedef long long ll;
const int MAXN = 1000010;
const int N = 10000;
struct EDGE {
    int to, next;
}edge[MAXN << 1];
struct ENODE {
    int u, v;
    ll w;
}node[MAXN];
int n, top, dep[MAXN], size[MAXN], u, v, w, head[MAXN];
ll ans;
char buf[N], *p = buf, *end = buf;
inline char Get_char() {
    if(p == end) {
        if(feof(stdin)) return 0;
        p = buf; end = buf + fread(buf, 1, N, stdin);
    }
    return *(p++);
}
inline void Get_int(int &x) {
    x = 0; char c(0);
    while(!isdigit(c = Get_char()));
    do {x = (x * 10) + (c - '0');}
    while(isdigit(c = Get_char()));
    return ;
}
inline void add_edge(int u, int v) {
    edge[++top].to = v;
    edge[top].next = head[u];
    head[u] = top;
    
    edge[++top].to = u;
    edge[top].next = head[v];
    head[v] = top;
    
    return ;
}
inline void dfs(int now, int fa) {
    size[now] = 1; int tmp(0);
    for (int i = head[now]; i; i = edge[i].next) 
        if((tmp = edge[i].to) != fa){
            dep[tmp] = dep[now] + 1;
            dfs(tmp, now);
            size[now] += size[tmp];
        }
    return ;
}
int main() {
    Get_int(n);
    for (int i = 1; i < n; ++i) {
        Get_int(u); Get_int(v); Get_int(w);
        add_edge(u, v);
        node[i].u = u; node[i].v = v; node[i].w = w;
    }
    dfs(1, 1);
    ll tmp(0);
    for (int i = 1; i < n; ++i) {
        u = node[i].u; v = node[i].v; tmp = node[i].w;
        if(dep[u] > dep[v]) std::swap(u, v);
        ans += tmp * std::abs(n - size[v] - size[v]);
    }
    printf("%lld\n", ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/manziqi/p/9789698.html