CodeForces1633

Div. 7

解析:

题目大意

给定 \(t\) 组数据。每组数据给定一个数 \(n\)(\(10\le n\le 999\))。

每次操作可以修改 \(n\) 任意一位上的数,将这一位上的数修改为 \(0\sim 9\) 之间的任意数。要求使用最少的修改次数使这个数修改后是 \(7\) 的倍数,并且没有多余的前导 \(0\)。输出修改后的数,如果有多组解,输出任意一种即可。如果已经是 \(7\) 的倍数,那么不需要修改。


思路:

发现修改个位一定能让 \(n\) 能被 \(7\) 整除,直接枚举个位换哪个数。


code

#include <bits/stdc++.h>
using namespace std;
signed main()
{
int t; scanf ("%d", &t);
while (t--)
{
int n; scanf ("%d", &n);
if (n % 7 == 0) printf ("%d\n", n);
else
{
n = n / 10 * 10;
for (int i = n; i <= n + 10; i++)
if (i % 7 == 0) { printf ("%d\n", i); break; }
}
}
return 0;
}

Minority

解析:

题目大意:
  • 给定一个 \(01\) 字符串 \(s\),定义 \(c_k(l,r)\) 表示 \(s\) 的由下标为 \([l,r]\) 中的字母构成的连续子串中 \(k\) 的个数。
  • 定义 \(f(l,r)=\begin{cases}c_0(l,r)&c_0(l,r)<c_1(l,r)\\c_1(l,r)&c_0(l,r)>c_1(l,r)\\0&c_0(l,r)=c_1(l,r)\end{cases}\),求 \(\max\limits_{1\le l\le r\le n}f(l,r)\)。多组询问。
  • \(T\le10^4,\sum|s|\le2\times10^5\)

思路:

诈骗题,\(f(1,n)\) 一定最大,因为这个区间含有的 \(0,1\) 都最多,如果 \(c_0(l,r)=c_1(l,r)\) 那个答案就是 \(c_0(l,r)-1\)(取 \([1,n-1]\))。


code:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
char ch[N];
int cnt1, cnt2;
signed main()
{
int t; scanf ("%d", &t);
while (t--)
{
cnt1 = cnt2 = 0;
scanf ("%s", ch + 1);
int n = strlen (ch + 1);
if (n <= 2) { printf ("0\n"); continue; }
for (int i = 1; i <= n; i++)
{
if (ch[i] == '0') cnt1++;
else cnt2++;
}
if (cnt1 != cnt2) printf ("%d\n", min(cnt1, cnt2));
else printf ("%d\n", cnt1 - 1);
}
return 0;
}

Kill the Monster

解析:

题目大意

在某款电脑游戏里,角色初始生命 \(hc\),初始攻击 \(dc\)。怪物初始生命 \(hm\),初始攻击 \(dm\)。

而你有 \(k\) 次机会,将攻击力永久提升 \(w\) 或者将生命永久提升 \(a\) 。

每一轮,角色攻击怪物,怪物掉 \(dc\) 生命。怪物攻击角色,角色掉 \(dm\) 生命。

问若干轮以后,角色能否击杀怪物并且角色存活。

击杀怪物定义为:怪物生命 \(\ngtr 0\)。

角色存活定义为:角色生命 \(>0\)。


思路:

枚举 \(0\to k\) 分别给攻击和生命多少次机会,如果某一时刻 $ \lceil\frac{hc}{dm}\rceil \ge \lceil\frac{hm}{dc}\rceil$ 那么就可以胜利。


code

#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read ()
{
int x = 0, f = 1;
char ch = getchar ();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar (); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar (); }
return x * f;
}
signed main()
{
int t = read ();
while (t--)
{
int hc = read (), dc = read ();
int hm = read (), dm = read ();
int k = read (), w = read (), a = read ();
bool flag = false;
for (int i = 0; i <= k; i++)
{
int h = hc + (i * a), d = dc + ((k - i) * w);
if ((hm + d - 1) / d <= (h + dm - 1) / dm) { printf ("YES\n"); flag = true; break; }
}
if (!flag) printf ("NO\n");
}
return 0;
}

Make Them Equal

解析:

题目大意:

你有一个长度为 \(n\),初始全为 \(1\) 的数组 \(a\),和两个长度为 \(n\) 的数组 \(b,c\)。

你可以最多进行 \(k\) 次如下的操作:选择两个正整数 \(i,x\),使 \(a_{i}\) 变成 $ \left ( a_{i}+\left \lfloor \dfrac{a_{i}}{x} \right \rfloor \right )$。

最后,如果 \(a_{i}=b_{i}\),你将会获得 \(c_{i}\) 的收益。

最大化总收益。

  • \(1 \leq t \leq 100,1 \leq n \leq 1000, 1 \leq k \leq 1 \times 10^{6}\)
  • \(1 \leq b_{i} \leq 1000,1 \leq c_{i} \leq 1 \times 10^{6}\);
  • \(\sum n \leq1000\)。

思路:

我们注意到 \(a_i\) 的初始值都是 \(1\),而 \(b_i\leq 1000\) 所以我们可以预处理出来每个值由 \(1\) 得到的最小次数,这部分预处理复杂度是 \(\mathcal O(V^2)\) 的。现在问题转化成了:

  • 最多操作 \(k\) 次,还原第 \(i\) 个需要操作 \(cnt_{b_i}\) 次,可以得到 \(c_i\) 的价值,问最大价值。

发现问题变成了 01背包问题,复杂度 \(\mathcal O(nk)\),可能会被卡常,注意 \(k\geq \sum cnt_{b_i}\) 可以剪枝。


code:

#include <bits/stdc++.h>
using namespace std;
const int N = 1000 + 10;
const int K = 1e6 + 10;
typedef pair <int, int> pii;
inline int read ()
{
int x = 0, f = 1;
char ch = getchar ();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar (); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar (); }
return x * f;
}
int n, k;
int b[N], c[N], cnt[N * 2];
int dp[K];
void init ()
{
memset (cnt, 0x3f, sizeof (cnt));
cnt[1] = 0;
for (int i = 1; i <= 1000; i++)
for (int j = 1; j <= i; j++)
cnt[i + i / j] = min (cnt[i + i / j], cnt[i] + 1);
}
signed main()
{
int t = read ();
init ();
while (t--)
{
n = read (), k = read (); int sum = 0, s = 0;
for (int i = 1; i <= n; i++) b[i] = read (), sum += cnt[b[i]];
for (int i = 1; i <= n; i++) c[i] = read (), s += c[i];
if (k >= sum) { printf ("%d\n", s); continue; }
memset (dp, 0, sizeof (dp));
for (int i = 1; i <= n; i++)
for (int j = k; j >= cnt[b[i]]; j--)
dp[j] = max (dp[j], dp[j - cnt[b[i]]] + c[i]);
printf ("%d\n", dp[k]);
}
return 0;
}

Spanning Tree Queries

解析:

题目大意:

给定一个包含 \(n\) 个点和 \(m\) 条边的无向带权图,你有 \(k\) 次询问,第 \(i\) 次询问给定一个整数 \(q_i\),你需要从图中选出一棵生成树,设该生成树的 \(n-1\) 条边的权值为 \(w_1,w_2,\dots,w_{n-1}\),你需要求出 \(\sum\limits_{j=1}^{n-1}|w_j-q_i|\) 的最小值。

该题所有 \(k\) 次询问中,前 \(p\) 次询问的 \(q_1,q_2,\dots,q_p\) 在输入中给定,从第 \(p+1\) 次询问开始的 \(q_i=(q_{i-1}\cdot a+b)\bmod c\)。

  • \(2\leqslant n\leqslant 50\),\(n-1\leqslant m\leqslant 300\),\(1\leqslant p\leqslant 10^5\),\(p\leqslant k\leqslant 10^7\),\(0\leqslant a,b\leqslant 10^8\),\(1\leqslant c\leqslant 10^8\)。
  • \(0\leqslant w_i\leqslant 10^8\)。

思路:

发现这道题的 \(k\leq 10^7\),也就是我们必须在 \(\log\) 的时间内处理每个答案,这样 \(\mathcal O(km\log m)\) 的 \(k\) 次 Kruskal 肯定不行,我们需要考虑预处理答案。

而绝对值有好的性质,我们按照边权排序后,正常 Kruskal 是从头到尾扫,而绝对值则要求先扫在数轴上更靠近 \(q_i\) 的边,我们可以二分找到 \(q_i\) 在边权 \(e_i\) 中的具体位置,并将边权分为两类:小于 \(q_i\) 和大于 \(q_i\) 的。

假设 \(e_1\le e_2\le\cdots\le e_j\le q_i\le e_{j+1} \le \cdots \le e_m\),

则必有 \(|e_1-q_i| \ge |e_2-q_i| \ge \cdots \ge |e_j-q_i|\) 且 \(|e_{j+1}-q_i| \le|e_{j+2}-q_i| \le \cdots \le |e_m-q_i|\),我们可以开两个队列分别从 \(j\to 1\),\(j+1\to m\) 维护每条边权,每次取两个队列中与 \(q_i\) 绝对值的较小值,这样就达到了排序的目的。

同时,我们注意到 \(m\leq 300\),也就是我们可以对每个 \(j\) 分别考虑,考虑每个 \(e_j\leq q\leq e_{j+1}\) 时的生成树情况,但对于即使对于同一个 \(j\),不同的 \(q\) 所对应的生成树也是可能不同的,即在两个队列中会造成不同的选数顺序,我们考虑这样的情况最多有 \(\begin{pmatrix} m \\ 2 \\ \end{pmatrix}\) 种不同的可能(在 \(m\) 条边中任选两条边取平均值),这样最终不同生成树的个数是 \(\mathcal O(m)\cdot\mathcal O(m^2)=\mathcal O(m^3)\) 种。

时间复杂度 \(\mathcal O(m^3\log m+k\log m^2)\)。


code:

#include <bits/stdc++.h>
#define int long long
#define eb emplace_back
#define lob lower_bound
using namespace std;
const int N = 300 + 10;
const int SN = 1e5 + 10;
const int INF = 0x3f3f3f3f;
typedef pair <int, int> pii;
inline int read ()
{
int x = 0, f = 1;
char ch = getchar ();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar (); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar (); }
return x * f;
}
int n, m;
int p, k, a, b, c;
struct edge {
int u, v, w;
bool operator < (const edge &A)const {
return w < A.w;
}
}e[N];
int g[SN], cnt;
int ans[SN], cntA[SN][2];
queue <int> que[2];
struct DSU {
int fa[N];
void init () { for (int i = 1; i <= n; i++) fa[i] = i; }
inline int find (int x) { return x == fa[x] ? x : fa[x] = find (fa[x]); }
} d;
void clear (int k) { while (!que[k].empty ()) que[k].pop (); }
void kruskal (int id, int x)
{
d.init ();
clear (0); clear (1);
int pos = lob (e + 1, e + m + 1, (edge) {0, 0, x}) - e;
for (int i = pos - 1; i >= 1; i--) que[0].push (i);
for (int i = pos; i <= m; i++) que[1].push (i);
while (!que[0].empty () || !que[1].empty ())
{
int c, cid;
if (que[0].empty ()) c = 1, cid = que[1].front ();
else if (que[1].empty ()) c = 0, cid = que[0].front ();
else
{
if (abs (x - e[que[0].front ()].w) <= abs (x - e[que[1].front ()].w)) c = 0, cid = que[0].front ();
else c = 1, cid = que[1].front ();
}
int fx = d.find (e[cid].u), fy = d.find (e[cid].v);
if (fx != fy)
{
d.fa[fx] = fy;
ans[id] += abs (x - e[cid].w);
cntA[id][c]++;
}
que[c].pop ();
}
}
int Xor;
inline int getans (int q)
{
int x = lob (g + 1, g + cnt + 1, q) - g;
return ans[x] - cntA[x][0] * (g[x] - q) + cntA[x][1] * (g[x] - q);
}
signed main()
{
n = read (), m = read ();
for (int i = 1; i <= m; i++)
e[i].u = read (), e[i].v = read (), e[i].w = read ();
sort (e + 1, e + m + 1);
for (int i = 1; i <= m; i++)
for (int j = 1; j <= m; j++)
g[++cnt] = (e[i].w + e[j].w) >> 1;
g[++cnt] = INF;
sort (g + 1, g + cnt + 1);
cnt = unique (g + 1, g + cnt + 1) - g - 1;
for (int i = 1; i <= cnt; i++) kruskal (i, g[i]);
p = read (), k = read (), a = read (), b = read (), c = read ();
int q;
for (int i = 1; i <= p; i++) { q = read (); Xor ^= getans(q); }
for (int i = p + 1; i <= k; i++) { q = (q * a + b) % c; Xor ^= getans(q); }
printf ("%lld\n", Xor);
return 0;
}

6

解析:

题目大意:


思路:

没读题,先咕了


code:


Educational Codeforces Round 122 (Rated for Div. 2)/codeforces1633的更多相关文章

  1. Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...

  2. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

  3. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  4. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

  5. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...

  6. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...

  7. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  8. Educational Codeforces Round 39 (Rated for Div. 2) G

    Educational Codeforces Round 39 (Rated for Div. 2) G 题意: 给一个序列\(a_i(1 <= a_i <= 10^{9}),2 < ...

  9. Educational Codeforces Round 48 (Rated for Div. 2) CD题解

    Educational Codeforces Round 48 (Rated for Div. 2) C. Vasya And The Mushrooms 题目链接:https://codeforce ...

随机推荐

  1. ChromePortable-Chrome便携化、绿化软件v2.0

    ChromePortable-Chrome便携化.绿化软件v2.0-用户手册 By:ybmj@vip.163.com ,http://bbs.kafan.cn/thread-1806385-1-1.h ...

  2. HTML(下)

    (一)表格标签 1.表格的作用 用于显示.展示数据,让数据更加规整,可读性更好,把繁琐的数据表现得很有条理,表格不是用来布局页面的,而是用来展示数据的 2.表格标签基本语法 table--table ...

  3. 聊一款可以自动跳过手机APP广告的神器!

    平时使用手机,很多APP都有开屏广告,有些短的一两秒,长的三五秒,用起来浪费时间不说,有时候想点击跳过,一不小心还可以点进广告,进行跳转,让人很不舒服. 今天我给小伙伴们推荐一个可以跳过APP开屏广告 ...

  4. apk编辑器测评

    hi你好,我今天要介绍的就是apk编辑器 这里我用的是apk编辑器专业版 APK编辑器 关于 APK 编辑器智友汉化组论坛:bbs.zhiyoo.com修改应用程序名称美化 UI: 更改背景图片删除广 ...

  5. 【Java】学习路径51-线程组

    平时创建线程的时候,系统会默认为线程分组. 我们可以使用 ThreadGroup tg1 = t1.getThreadGroup(); 取得t1的线程组对象. 然后使用getName获得线程组名称. ...

  6. 小结event.target与this

    <!DOCTYPE html> <html> <head>     <meta charset="UTF-8">     <t ...

  7. 01-MyBatisPlus简介

    一.简介 官网:http://mp.baomidou.com/ 参考教程:https://baomidou.com/pages/24112f/ MyBatis-Plus(简称 MP)是一个 MyBat ...

  8. 使用脚本在FTP上传、下载文件

    由于最近勒索病毒变种又一次爆发,公司内部封锁了TCP 445端口.导致原来通过文件共享的方式上传下载的计划任务无法执行.所以,我开设了FTP服务器来完成这个工作. 关于如何建立FTP服务器,请看这里 ...

  9. CAP 6.2 版本发布通告

    前言 今天,我们很高兴宣布 CAP 发布 6.2 版本正式版,在这个版本中我们主要做了一些功能优化,以及针对目前已经发现的几个 BUG 进行了修复了. 那么,接下来我们具体看一下吧. 总览 可能有些人 ...

  10. windows下 Rust 环境配置

    搭建 Visual Studio Code 开发环境 首先,需要安装最新版的 Rust 编译工具和 Visual Studio Code. Rust 编译工具:https://www.rust-lan ...