A - Minimizing the String

solved

题意:给出一个字符串,可以移掉最多一个字符,在所有可能性中选取一个字典序最小的。

思路:显然,一定可以移掉一个字符,如果移掉的字符的后一个字符大于当前字符,那么字典序会变大。

那只需要从左往右,遇到第一个后面的字符大于当前字符的就可以移掉该字符。

 #include <bits/stdc++.h>
using namespace std; #define N 200010
int n;
char s[N]; int main()
{
while (scanf("%d%s", &n, s + ) != EOF)
{
int pos = n;
for (int i = ; i < n; ++i) if (s[i + ] < s[i])
{
pos = i;
break;
}
s[pos] = ;
printf("%s", s + );
printf("%s\n", s + pos + );
}
return ;
}

B - Divisor Subtraction

solved

题意:给出一个数n,如果n = 0,那么程序就结束。否则减去这个数的最小质因子,再循环执行该算法,问程序会执行多少步。

思路:

我们假设数$n的最小质因子为x, 令 y = \frac{n}{x}$

如果$y$是偶数,那么答案就很明显,直接不断减去2

如果$y是奇数,那么我们先减去一个x, 那么就会变成 n = (y - 1) \cdot x$

$此时 (y - 1) 显然为偶数 就不断减去2就可以$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
ll x; ll find(ll x)
{
ll limit = sqrt(x + );
for (ll i = ; i <= limit; ++i) if (x % i == ) return i;
return x;
} int main()
{
while (scanf("%lld", &x) != EOF)
{
ll y = find(x); ll z = x / y;
printf("%lld\n", (z - ) * y / + );
}
return ;
}

C - Meme Problem

solved

题意:给出一个$d, 找a + b = d and a \cdot b = d$

思路:将$a = d - b$ 代入第二个式子,解二元一次方程。

 #include <bits/stdc++.h>
using namespace std; int t, d; int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &d);
if (d * d < * d) puts("N");
else
{
double delta = sqrt(d * d - * d);
double b = (d - delta) / ;
double a = d - b;
printf("Y %.10f %.10f\n", a, b);
}
}
return ;
}

D - Edge Deletion

Upsolved

题意:给出一个无向图,定义$d_i为 1 - i 的最短路径$,定义一个点为好点为1 - 这个点的最短路径为 $d_i$,最多保留k条边,使得剩下的点中好点最多。

思路:Dijkstra构造最短路树,对最短路树DFS或者BFS皆可,按这个搜索顺序选取边,显然每选取一条边都会增加一个好点,所以最后好点的数量显然为$min(k + 1, n)$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define INFLL 0x3f3f3f3f3f3f3f3f
#define N 300010
int n, m, k; struct Edge
{
int u, v; ll w;
Edge() {}
Edge(int u, int v, ll w) : u(u), v(v), w(w) {}
}edge[N]; struct graph
{
struct node
{
int to, nx, id; ll w;
node () {}
node (int to, int nx, int id, ll w) : to(to), nx(nx), id(id), w(w) {}
}a[N << ];
int head[N], pos;
void init() { memset(head, , sizeof head); pos = ; }
void add(int u, int v, int id, ll w)
{
a[++pos] = node(v, head[u], id, w); head[u] = pos;
a[++pos] = node(u, head[v], id, w); head[v] = pos;
}
}G, g;
#define erp(G, u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w; it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w) struct Dijkstra
{
struct node
{
int to; ll w;
node () {}
node (int to, ll w) : to(to), w(w) {}
bool operator < (const node &r) const { return w > r.w; }
};
struct DIST
{
ll w; int id;
DIST() {}
DIST(ll w, int id) : w(w), id(id) {}
}dist[N]; bool used[N];
void solve()
{
for (int i = ; i <= n; ++i)
{
dist[i] = DIST(INFLL, -);
used[i] = false;
}
dist[] = DIST(, -);
priority_queue <node> q; q.emplace(, );
while (!q.empty())
{
int u = q.top().to; q.pop();
if (used[u]) continue;
used[u] = ;
int id = dist[u].id; if (id != -) g.add(edge[id].u, edge[id].v, id, edge[id].w);
erp(G, u) if (!used[v] && dist[v].w > dist[u].w + w)
{
dist[v].w = dist[u].w + w;
dist[v].id = G.a[it].id;
q.emplace(v, dist[v].w);
}
}
}
}dij; vector <int> res;
void DFS(int u, int fa)
{
erp(g, u) if (v != fa && res.size() < k)
{
res.push_back(g.a[it].id);
DFS(v, u);
}
} int main()
{
while (scanf("%d%d%d", &n, &m, &k) != EOF)
{
G.init(); g.init(); res.clear();
for (int i = , u, v, w; i <= m; ++i)
{
scanf("%d%d%d", &u, &v, &w);
edge[i] = Edge(u, v, w);
G.add(u, v, i, w);
} dij.solve(); DFS(, );
int len = res.size();
printf("%d\n", len);
for (int i = ; i < len; ++i) printf("%d%c", res[i], " \n"[i == len - ]);
}
return ;
}

E - Vasya and a Tree

solved

题意:给出一棵树,有m次操作,每次将以x为根的子树下,和x的距离不超过d的所有点的权值都加上v,最后输出每个点的权值。

思路:首先考虑$d$特别大的情况下,也就是子树下所有点都要加上,那么更新的时候直接在那个点上更新,

最后只需要DFS一遍,每个点都加上父亲的权值即可。

再考虑加入限制的情况:

其实对于一个点,我们DFS下去的时候,到回溯上来这段时间,遍历的都是它的子树,那么我们可以设立一个标记

对于每个点,给他加上更新的权值的时候,我们在对应的子树的deep界限那里加上,那么每次遍历下去的时候,首先要减去这个当前深度对应的lazy值,然后再更新答案,回溯上来的时候取消标记即可。

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 300010
#define pii pair <int, int>
int n, m;
vector <int> G[N];
vector <pii> vec[N];
ll ans[N], gap[N]; int deep[N], fa[N];
void DFS(int u, ll res)
{
res -= gap[deep[u]];
for (auto it : vec[u])
{
int dep = min(deep[u] + it.first + , n + );
gap[dep] += it.second;
res += it.second;
}
ans[u] = res;
for (auto v : G[u]) if (v != fa[u])
{
fa[v] = u;
deep[v] = deep[u] + ;
DFS(v, res);
}
for (auto it : vec[u])
{
int dep = min(deep[u] + it.first + , n + );
gap[dep] -= it.second;
res -= it.second;
}
res += gap[deep[u]];
} void init()
{
for (int i = ; i <= n; ++i)
{
G[i].clear();
vec[i].clear();
}
memset(gap, , sizeof gap);
deep[] = ;
} int main()
{
while (scanf("%d", &n) != EOF)
{
init();
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
scanf("%d", &m);
for (int i = , x, d, v; i <= m; ++i)
{
scanf("%d%d%d", &x, &d, &v);
vec[x].emplace_back(min(d, n), v);
}
DFS(, );
for (int i = ; i <= n; ++i) printf("%lld%c", ans[i], " \n"[i == n]);
}
return ;
}

F. Summer Practice Report

Upsolved.

题意:

$第i天有x_i个糖果,y_i个果冻,要求将他们放在一排,且相同的东西连续最多放k个,要放n天,求是否有放置方案满足$

思路:

$dp[i][1/0] 表示第i天最后一部分放糖果还是果冻的最小数量,然后枚举四种状态DP转移即可。$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define INF 0x3f3f3f3f
#define N 300010
int n, k, x[N], y[N], dp[N][]; int calc(int pa, int pb, int a, int b)
{
int ans = INF;
if (pa <= k)
{
int tot = pa + a;
int cnt = (tot + k - ) / k - ;
if (b == cnt) ans = min(ans, tot - cnt * k);
else if (b > cnt && b <= (ll)a * k) ans = min(ans, );
}
if (pb <= k)
{
int cnt = (a + k - ) / k - ;
if (b == cnt) ans = min(ans, a - cnt * k);
else if (b > cnt && b <= (ll)a * k - pb) ans = min(ans, );
}
return ans;
} bool solve()
{
memset(dp, 0x3f, sizeof dp); dp[][] = dp[][] = ;
for (int i = ; i <= n; ++i)
{
dp[i][] = calc(dp[i - ][], dp[i - ][], x[i], y[i]);
dp[i][] = calc(dp[i - ][], dp[i - ][], y[i], x[i]);
if (dp[i][] == INF && dp[i][] == INF) return false;
}
return true;
} int main()
{
while (scanf("%d%d", &n, &k) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", x + i);
for (int i = ; i <= n; ++i) scanf("%d", y + i);
puts(solve() ? "YES" : "NO");
}
return ;
}

G. Array Game

Unsolved.

Educational Codeforces Round 54 (Rated for Div. 2) Solution的更多相关文章

  1. Educational Codeforces Round 54 (Rated for Div. 2) D:Edge Deletion

    题目链接:http://codeforces.com/contest/1076/problem/D 题意:给一个n个点,m条边的无向图.要求保留最多k条边,使得其他点到1点的最短路剩余最多. 思路:当 ...

  2. Educational Codeforces Round 54 [Rated for Div. 2] (CF1076)

    第一次在宿舍打CF 把同宿舍的妹子吵得不行... 特此抱歉QAQ A 题意:给定一个字符串, 最多删掉一个字符,使得剩余字符串字典序最小 n<=2e5 当然"最多"是假的 删 ...

  3. Educational Codeforces Round 54 (Rated for Div. 2) DE

    D 给出一个无向图,需要删去一些边,想知道最后能有多少个点到1的距离还是过去那么短 如果求一个最短路,然后从删边的角度看,看起来很难做,但是如果从零开始加边就会有做法,如同prim那样,先加入和1直接 ...

  4. Educational Codeforces Round 54 (Rated for Div. 2) ABCD

    A. Minimizing the String time limit per test 1 second memory limit per test 256 megabytes Descriptio ...

  5. Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)

    题目大意:给定你一个包含n个点m条边的无向图,现在最多在图中保留k条边,问怎么删除多的边,使得图中良好的节点数最多,求出保留在图中的边的数量和编号. 良好的节点定义为:删除某条边后该点到点1的最短距离 ...

  6. Educational Codeforces Round 62 (Rated for Div. 2) Solution

    最近省队前联考被杭二成七南外什么的吊锤得布星,拿一场Div. 2恢复信心 然后Div.2 Rk3.Div. 1+Div. 2 Rk9,rating大涨200引起舒适 现在的Div. 2都怎么了,最难题 ...

  7. Educational Codeforces Round 40 (Rated for Div. 2) Solution

    从这里开始 小结 题目列表 Problem A Diagonal Walking Problem B String Typing Problem C Matrix Walk Problem D Fig ...

  8. Educational Codeforces Round 55 (Rated for Div. 2) Solution

    A. Vasya and Book Solved. 三种方式取$Min$ #include <bits/stdc++.h> using namespace std; #define ll ...

  9. Educational Codeforces Round 71 (Rated for Div. 2) Solution

    A. There Are Two Types Of Burgers 题意: 给一些面包,鸡肉,牛肉,你可以做成鸡肉汉堡或者牛肉汉堡并卖掉 一个鸡肉汉堡需要两个面包和一个鸡肉,牛肉汉堡需要两个面包和一个 ...

随机推荐

  1. 微信jssdk批量添加卡券接口(踩坑经验)

    1)首先是官方接口文档: 1.批量添加卡券接口:https://mp.weixin.qq.com/wiki?action=doc&id=mp1421141115&t=0.0861973 ...

  2. abs()

    abs() 用于返回一个数值的绝对值 In [1]: abs(10) Out[1]: 10 In [2]: abs(-10) Out[2]: 10 In [3]: abs(-10.9) Out[3]: ...

  3. iOS 数据类型转换

    1.NSString转化为UNICODE String:(NSString*)fname = @“Test”; char fnameStr[10]; memcpy(fnameStr, [fname c ...

  4. C++中的抽象基类示例

    抽象基类(abstract base class,ABC)例子:圆与椭圆.建立一个基类BaseEllipse,建立它的恋歌继承了Ellipse和Circle.ellipse.h #ifndef ELL ...

  5. JavaScript的记忆函数真的可以提升性能吗?

      1 记忆函数是什么呢? 让函数记住曾经计算过的参数对应的结果 2 那我们为什么使用记忆函数呢? 答案是 避免重复计算 3 在工作中如何使用和实现函数记忆 ? 形成闭包,在闭包中维护一个哈希数组(其 ...

  6. 微信小游戏 小程序与小游戏获取用户信息接口调整 wx.createUserInfoButton

    参考: 小程序•小故事(6)——微信登录能力优化 小程序•小故事(4)——获取用户信息 本篇主要是讲微信getUserInfo接口不再出现授权弹框 那么原来getUserInfo是怎么样?修改之后又是 ...

  7. 【BZOJ3012】[Usaco2012 Dec]First! Trie树+拓补排序

    [BZOJ3012][Usaco2012 Dec]First! Description Bessie has been playing with strings again. She found th ...

  8. Inflater与findViewById()区别

    /** * Inflater英文意思是膨胀,在Android中应该是扩展的意思吧. LayoutInflater的作用类似于 * findViewById(),不同点是LayoutInflater是用 ...

  9. angular -- 自定义指令和模板

    angular 可以自定义一些指令,来简化我们前端的工作量. 第一种:简单指令示例: <h3>自定义指令</h3> <sheng></sheng> &l ...

  10. PreparedStatement vs Statement

    Statement和PreparedStatement之间的区别 1.PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程   2.使用 Statemen ...