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;
}