ECNA 2014 部分题解 | 训练记录0703
Posted PushyTao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ECNA 2014 部分题解 | 训练记录0703相关的知识,希望对你有一定的参考价值。
目录
D. Generalized Roman Numerals [思维dp]
dp
#pragma GCC optimize(2)
#pragma GCC optimize(3)
unordered_set<int> save[maxn][maxn];
int mp[1000];
int num[10000007];
void QuickSort(int l,int r)
if(l>=r) return;
int left=l,right=r;//
ll temp=num[(left+right)/2];//设左边的为基值
int mid=(left+right)/2;
while(left<right) //相等的 return;就可以了
while(num[left]<temp) left++;
while(num[right]>temp) right--;
if(left<=right)
ll stemp=num[left];
num[left]=num[right];
num[right]=stemp;
left++;
right--;
QuickSort(l,right);
QuickSort(left,r);
int main()
mp['I'] = 1;
mp['V'] = 5;
mp['X'] = 10;
mp['L'] = 50;
mp['C'] = 100;
char s[55];
int kase = 0;
while(scanf("%s",s) != EOF)
if(s[0] == '0') break;
int len = strlen(s);
for(int i=0; i<=len; i++)
for(int j=0; j<=len; j++)
save[i][j].clear();
for(int i=0; i<len; i++)
save[i][i].insert(mp[s[i]]);//自己到自己只能是当前字符
// meiju 长度
for(register int i=2; i<=len; i++)
for(register int j=0; j+i<=len; j++)
int st = j;
int ed = j+i-1;
//ed - st + 1 => length=i
for(register int md=j; md<ed; ++md)
for(auto A : save[st][md])
for(auto B : save[md+1][ed])
if(A >= B) save[st][ed].insert(A + B);
else save[st][ed].insert(- A + B);
vector<int> v;
int idx = 0;
for(int x:save[0][len-1]) v.push_back(x);
// for(int x:save[0][len-1])
// num[++idx] = x;
//
sort(v.begin(), v.end());
// sort(num+1,num+1+idx);
// QuickSort(1, idx);
// v.erase(unique(v.begin(), v.end()),v.end());
printf("Case %d: ",++kase);
// for(int x: v) printf("%d ", x);
for(int i=0; i<v.size(); i++)
printf("%d%c",v[i],i == v.size()-1?'\\n':' ');
// puts("");
// for(int i=1; i<=idx; i++)
// printf("%d%c",num[i],i == idx?'\\n':' ');
//
return 0;
E. Inspectors [拆点跑最小费用最大流]
/*** keep hungry and calm PushyTao!***/
typedef pair<ll, ll> PLL;
struct Edge
int u, v, cap, flow, cost;
Edge(int _u, int _v, int _cap, int _flow, int _cost)
u = _u, v = _v, cap = _cap, flow = _flow, cost = _cost;
;
struct MinCostMaxFlow
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
int vis[maxn], dis[maxn], p[maxn], a[maxn];
void init(int x)
this->n = x;
for (int i = 0; i <= x; i++) G[i].clear();
edges.clear();
void add(int u, int v, int cap, int cost)
edges.push_back(Edge(u, v, cap, 0, cost));
edges.push_back(Edge(v, u, 0, 0, -cost));
m = edges.size();
G[u].push_back(m - 2);
G[v].push_back(m - 1);
bool BellmanFord(int s, int t, ll &flow, ll &cost)
for (int i = 0; i <= n; i++) dis[i] = 0x3f3f3f3f;
memset(vis, 0, sizeof vis);
queue<int> que;
que.push(s);
dis[s] = 0, vis[s] = 0, p[s] = 0, a[s] = 0x3f3f3f3f;
while (que.size())
int u = que.front();
que.pop();
vis[u] = 0; /// not in the queue
for (int i = 0; i < G[u].size(); i++)
int id = G[u][i];
Edge e = edges[id];
int to = e.v;
if (e.cap > e.flow && dis[to] > dis[u] + e.cost)
dis[to] = dis[u] + e.cost;
p[to] = id;
a[to] = min(a[u], e.cap - e.flow);
if (!vis[to])
que.push(to);
vis[to] = 1;
if (dis[t] >= 0x3f3f3f3f) return false;
flow += a[t];
cost += 1LL * dis[t] * 1LL * a[t];
for (int u = t; u != s; u = edges[p[u]].u)
edges[p[u]].flow += a[t];
edges[p[u] ^ 1].flow -= a[t];
return true;
PLL MinCostAndMaxFlow(int s, int t)
ll flow = 0;
ll cost = 0;
while (BellmanFord(s, t, flow, cost));
return flow, cost;
solve;
int n, m, s, t;
int main()
/**
cin >> n >> m >> s >> t;
solve.init(n);
for (int i = 1; i <= m; i++)
int u = read, v = read, flow = read, cost = read;
solve.add(u, v, flow, cost);
PLL ans = solve.MinCostAndMaxFlow(s, t);
cout << ans.first << ' ' << ans.second << endl;
**/
int _ = read;
for(int kase=1; kase<=_; kase++)
n = read;
solve.init(1003);
for(int i=1; i<=n; i++)
solve.add(0,i,1,0);// s <-> i_in
solve.add(i+n,1001,1,0);// i_out <-> t
for(int j=i+1; j<=n; j++)
int value = read;
solve.add(i,j+n,1,value);// in_i <-> j_out
solve.add(j,i+n,1,value);// in_j <-> i_out
PLL p = solve.MinCostAndMaxFlow(0,1001);
// cout << p.first << endl;
printf("Case %d: %d\\n",kase, p.second);
return 0;
/**
2
4
10 20 10
10 20
10
4
15 20 10
10 20
15
->
Case 1: 40
Case 2: 40
**/
H. Time Warp [模拟]
/*** keep hungry and calm PushyTao!***/
void print(int kase, ll seco)
int h,m,s;
h = m = s = 0;
seco = (seco + 12 * 60 * 60) % (12 * 60 * 60);//;//
h = seco / 3600 + 1;
m = seco % 3600 / 60;
s = seco % 60;
printf("Case %d: %d:%02d:%02d\\n",kase, h,m,s);
void solve(int a,int b,string c,int kase)
if(c[0] == 'a')
int cur = 30 * (12 - b);
int need = 0;
if(a > cur) need = a - cur;
else need = 360 - cur + a;
int t = round(need / (11.0 / 120.0));
print(kase, 3600 * (b - 1) + t);
else if(c[0] == 't')
int cur = 30 * (12 - b);
int need = 0;
if(a < cur) need = -(a - cur);
else need = 360 + cur - a;
int t = round(need / (11.0 / 120.0));
print(kase, 3600 * (b - 1) - t);
int main()
int _ = read;
int kase;
for(kase = 1; kase <= _; kase++)
string c;
int a = read;
cin >> c;
int b = read;
solve(a,b,c,kase);
return 0;
/**
**/
A. Cure for the Common Code [KMP]
#include <bits/stdc++.h>
typedef long long ll;
template<typename T>
std::istream& operator>> (std::istream& in, std::vector<T>& vt)
for (auto& i : vt) in >> i;
return in;
template<typename T>
std::ostream& operator<< (std::ostream& out, const std::vector<T>& vt)
for (auto& i : vt) out << i << " ";
out << std::endl;
return out;
void printAll()
template<typename T1, typename... T2>
void printAll(const T1& first, const T2&... second)
std::cout << first;
if (sizeof...(second))
std::cout << ", ";
printAll(second...);
template<typename T1, typename... T2>
void print(const T1& first, const T2&... second)
std::cout << "[";
printAll(first, second...);
std::cout << "]" << std::endl;
#define N (int)(5e2 + 10)
struct Kmp
static int nxt[N];
// nxt[i]
// 表示前i个字母,下标应该转移到nex[i]
// 本质含义是最长前后缀,但是由于字符串从0开始计数的,所以正好指向的是最长前后缀的前缀的下一个位置,即需要匹配的位置
private:
static void init()
memset(nxt, 0, sizeof(nxt));
public以上是关于ECNA 2014 部分题解 | 训练记录0703的主要内容,如果未能解决你的问题,请参考以下文章
[bfs,深度记录] East Central North America Regional Contest 2016 (ECNA 2016) D Lost in Translation