Beautiful Regional Contest

题目链接 http://codeforces.com/contest/1264/problem/A

题意

给出区域赛中 N 支队伍做出的题数,在一定规则下发奖时,金银铜牌奖牌数总和的最大值。
要求:

  1. 合法方案中每种奖牌至少一个
  2. 金牌数严格少于银牌和铜牌数,银牌和铜牌数间没有要求
  3. 金牌队伍解题数必须严格大于银牌队伍解题数,银铜、铜铁同理。
  4. 奖牌总数和不能超过队伍总数的一半(21支队伍时奖牌数至多10,26支队伍将牌至多13)。

题解

首先根据 要求4,去除一定不可能得奖的后一半人。
因为 要求2 只要求银铜的奖牌数多于金牌,所以直接使金牌数为最少(解题最多的那些队伍),然后从剩下的队伍中找到足够多的队伍得银牌(前缀和然后二分),剩下得铜牌即可。
注意中间发现无法满足要求时及时结束代码。

代码

/*
* Codeforces Round #604
* Beautiful Regional Contest
*/
#include <cstdio>
#include <algorithm>
using namespace std;
int N;
int ls[400010];
void work() {
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", ls+i);
}
int j, nu;
nu = ls[0];
ls[0] = 1;
j = 0;
for (int i = 1; i < N; i++) {
if (ls[i] == nu) {
ls[j]++;
}
else {
nu = ls[i];
j++;
ls[j] = 1;
}
}
int sm = 0;
for (int i = j; i >= 0; i--) {
sm += ls[i];
if (sm*2 >= N) {
j = i;
break;
}
}
if (j < 3) {
printf("0 0 0\n");
return;
}
for (int i = 1; i < j; i++) {
ls[i] += ls[i-1];
}
int a, b, c;
a = ls[0];
int *it;
it = lower_bound(ls, ls+j, a*2+1);
if (it == ls+j)
a = b = c = 0;
else {
b = *it - a;
c = ls[j-1] - *it;
if (!a || !b || !c || a>=c) {
a = b = c = 0;
}
}
printf("%d %d %d\n", a, b, c);
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
work();
}
return 0;
}

Beautiful Sequence

题目链接 http://codeforces.com/contest/1264/problem/B

题意

给出 0, 1, 2, 3 四种数字的个数 a, b, c, d,要求构造数列,满足相邻数字相差为1。

题解

可以知道 0 只能和 1 相邻,当有多个 0 时,一定是通过 010101 这样的序列消耗掉 0 的,对于 3 同理,通过 232323 消耗。
优先考虑用 1 消耗尽可能多的 0,用 2 消耗尽可能多的 3。
剩下的 1 和 2 一定是通过 212121 的序列消耗的。
根据上述规则构成 010121212323 序列中的三部分 0101 2121 2323。
此外,恰好多出一个 1 和 2 时可以放在开头和结尾形成 1 0101 2121 2323 2。
多出 0 和 3 时,以 0 为例,构成 0101 0 时需要保证没有 2 和 3,因为 2 和 3 都不能接在 0 的后面。

按照如上分析实现代码即可。
实际做题过程中,通过理清思路可以让编码难度直线下降。
当前思路为,优先考虑 01 和 23 成对消耗,然后考虑剩余 12 成对消耗,最后处理多余数字的情况。这是因为成对消耗可以看作是化简问题的过程,处理多余数字是特判的过程。
如果混用这两部分的话,容易出错漏情况。

代码

/*
* Codeforces Round #604
* Beautiful Sequence
*/
#include <cstdio>
#include <algorithm>
using namespace std;
int a, b, c, d;
int main() {
scanf("%d %d %d %d", &a, &b, &c, &d);
int A, B, C, D;
int u;
A = a;
B = b;
C = c;
D = d; u = min(A, B);
A -= u;
B -= u;
u = min(C, D);
C -= u;
D -= u;
u = min(B, C);
B -= u;
C -= u;
if (A > 1 || B > 1 || C > 1 || D > 1)
goto be;
if ((A && (c||d)) || (D && (a||b)))
goto be;
he:
printf("YES\n");
if (B)
printf("1 ");
u = min(a, b);
for (int i = 0; i < u; i++)
printf("0 1 ");
if (A)
printf("0 ");
u = min(b - min(a, b), c - min(c, d));
for (int i = 0; i < u; i++)
printf("2 1 ");
if (D)
printf("3 ");
u = min(c, d);
for (int i = 0; i < u; i++)
printf("2 3 ");
if (C)
printf("2 ");
printf("\n");
return 0;
be:
printf("NO\n");
return 0;
}

一个思路不够清晰的代码

/*
* Codeforces Round #604
* Beautiful Sequence
*/
#include <cstdio>
#include <algorithm>
using namespace std;
int a, b, c, d;
int main() {
scanf("%d %d %d %d", &a, &b, &c, &d);
int A, B, C, D;
int u;
A = a;
B = b;
C = c;
D = d; // 从这里开始
u = min(A, B);
A -= u;
B -= u;
u = min(C, D);
C -= u;
D -= u; if (A > 1 || D > 1)
goto be;
if (A && (c||d))
goto be;
if (D && (a||b))
goto be;
int uBC;
uBC = u = min(B, C);
B -= u;
C -= u;
if (B > 1 || C > 1)
goto be;
// 到这里
he:
printf("YES\n");
if (B)
printf("1 ");
u = min(a, b);
for (int i = 0; i < u; i++)
printf("0 1 ");
if (A)
printf("0 ");
u = uBC;
for (int i = 0; i < u; i++)
printf("2 1 ");
if (D)
printf("3 ");
u = min(c, d);
for (int i = 0; i < u; i++)
printf("2 3 ");
if (C)
printf("2 ");
printf("\n");
return 0;
be:
printf("NO\n");
return 0;
}

Beautiful Mirrors with queries

题目链接 https://codeforces.com/contest/1264/problem/C

题意

N 个节点依次排列,每天尝试通过一个节点,每个节点有 \(P_i\) 的概率通过,下一天尝试第 i+1 个节点,如果没通过,下一天尝试通过前面最近的存档点。
求成功通过最后一个节点需要天数的期望。
Q 次询问,每次给出一个编号 u,修改 u 是否为检查点,并且输出修改后的答案。
1 号节点始终为存档点。
题中 \(P_i\) 以 \(\frac{p_i}{100}\) 的形式给出。

题解

如果没有检查点的修改,显然可以通过如下递推式计算答案,其中 \(F_i\) 表示从起点走到 i 号点需要天数的期望。
\[ F_i = F_{i-1} + P_i*1 + (1-P_i)(F_i+1) \]
在经过了前 \(i-1\) 个节点之后,\(P_i\) 的概率一次尝试并通过,\(1-P_i\)的概率退回存档点重新开始。

或者可以用一个通项公式来求,\(E\) 表示通过全部节点的期望天数。
\[ E = P_1(1+P_2(1+\dots)+(1-P_2)(1+E)) + (1-P_1)(1+E) \]
化简式子:
\[ \begin{aligned}
E =& (P_1 + P_1P_2 +\dots+ P_1\dots P_N)\\
&+[(1-P_1)(1+E) + P_1(1-P_2)(1+E) +\dots+ P_1\dots P_{N-1}(1-P_N)(1+E)]\\
=& (P_1 + P_1P_2 +\dots+ P_1\dots P_N) + (1-P_1\dots P_N)(1+E)\\
=& (1 + P_1 + P_1P_2 +\dots+ P_1\dots P_{N-1}) + (1-P_1\dots P_N)E
\end{aligned} \]

\[
E = \frac{A}{B} = \frac{1+P_1+P_1P_2+\dots+P_1\dots P_{N-1}}{P_1P_2\dots P_N}
\]

对于多个检查点的情况,可以发现,检查点分开的两段可以单独处理
即存在 x 号节点是检查点时,可以分别计算 \(E_{1,x-1}\) 和 \(E_{x,N}\) 然后求和就是总答案。
更一般的,有:
\[
E_{u,v} = \frac{A_{u,v}}{B_{u,v}} = \frac{1+P_u+P_uP_{u+1}+\dots+P_u\dots P_{v-1}}{P_uP_{u+1}\dots P_v}
\]
分别计算检查点隔开的每一段即可。
在 a, c 之间添加新的检查点 b 时,删除 (a, c-1),增加 (a, b-1), (b, c-1)。
删除时相反。
可以用 set 直接维护检查点。

代码

/*
* Codeforces Round #604
* Beautiful Mirrors with queries
*/
#include <cstdio>
#include <set>
using namespace std;
#define Nmax 200010
typedef long long LL;
LL MD = 998244353;
LL fpw(LL a, LL b) {
LL ans = 1;
while (b) {
if (b & 1)
ans = ans * a % MD;
a = a * a % MD;
b >>= 1;
}
return ans;
}
inline LL re(LL a) {
return fpw(a, MD - 2);
}
int N, Q;
LL P[Nmax];
LL mt[Nmax];
LL sm[Nmax];
LL ans;
set<int> st;
LL getans(int a, int b) {
LL p;
p = (((sm[b-2]-sm[a-1])%MD+MD)%MD
* re(mt[a-1]) %MD + 1)%MD
* re(mt[b-1]*re(mt[a-1])%MD) %MD;
return p;
}
void init() {
LL hdr;
hdr = re(100);
mt[0] = 1;
sm[0] = 0;
for (int i = 1; i <= N; i++) {
P[i] = P[i] * hdr % MD;
mt[i] = mt[i-1] * P[i] % MD;
sm[i] = sm[i-1] + mt[i] % MD;
}
st.insert(1);
st.insert(N+1);
ans = (sm[N-1]+1)%MD * re(mt[N]) % MD;
}
int main() {
scanf("%d %d", &N, &Q);
for (int i = 1; i <= N; i++) {
scanf("%lld", P+i);
}
init();
int x, y, z;
set<int>::iterator it;
for (int i = 0; i < Q; i++) {
scanf("%d", &x);
if (st.count(x)) {
it = st.find(x);
it--;
y = *it;
it++;
it++;
z = *it;
st.erase(x);
ans = ((ans-getans(y, x))%MD+MD)%MD;
ans = ((ans-getans(x, z))%MD+MD)%MD;
ans = (ans+getans(y, z))%MD;
}
else {
st.insert(x);
it = st.find(x);
it--;
y = *it;
it++;
it++;
z = *it;
ans = ((ans-getans(y, z))%MD+MD)%MD;
ans = (ans+getans(y, x))%MD;
ans = (ans+getans(x, z))%MD;
}
printf("%lld\n", ans);
}
return 0;
}

Codeforces Round #604的更多相关文章

  1. Codeforces Round #604(Div. 2,

    // https://codeforces.com/contest/1265/problem/D /* 感觉像是遍历的思维构造题 有思路就很好做的 可以把该题想象成过山车或者山峰...... */ # ...

  2. Codeforces Round #604 (Div. 2) E. Beautiful Mirrors

    链接: https://codeforces.com/contest/1265/problem/E 题意: Creatnx has n mirrors, numbered from 1 to n. E ...

  3. Codeforces Round #604 (Div. 2) D. Beautiful Sequence(构造)

    链接: https://codeforces.com/contest/1265/problem/D 题意: An integer sequence is called beautiful if the ...

  4. Codeforces Round #604 (Div. 2) C. Beautiful Regional Contest

    链接: https://codeforces.com/contest/1265/problem/C 题意: So the Beautiful Regional Contest (BeRC) has c ...

  5. Codeforces Round #604 (Div. 2) B. Beautiful Numbers

    链接: https://codeforces.com/contest/1265/problem/B 题意: You are given a permutation p=[p1,p2,-,pn] of ...

  6. Codeforces Round #604 (Div. 2) A. Beautiful String

    链接: https://codeforces.com/contest/1265/problem/A 题意: A string is called beautiful if no two consecu ...

  7. Codeforces Round #604 (Div. 2) E. Beautiful Mirrors 题解 组合数学

    题目链接:https://codeforces.com/contest/1265/problem/E 题目大意: 有 \(n\) 个步骤,第 \(i\) 个步骤成功的概率是 \(P_i\) ,每一步只 ...

  8. Codeforces Round #604 (Div. 2) 部分题解

    链接:http://codeforces.com/contest/1265 A. Beautiful String A string is called beautiful if no two con ...

  9. Codeforces Round #604 (Div. 2) A. Beautiful String(贪心)

    题目链接:https://codeforces.com/contest/1265/problem/A 题意 给出一个由 a, b, c, ? 组成的字符串,将 ? 替换为 a, b, c 中的一个字母 ...

随机推荐

  1. A1135 | 红黑树判断:审题、根据“先序遍历”和“BST树”的条件生成后序遍历、递归判断

    对A1135这题有心里阴影了,今天终于拿下AC.学习自柳神博客:https://www.liuchuo.net/archives/4099 首先读题很关键: There is a kind of ba ...

  2. SpringCloud基本模块分配搭建以及负载均衡

    springcloud是基于springboot的一套微服务的解决方案,springboot可以快速构建单个应用服务,而springcloud没有重复造轮子而是将现有的技术(服务发现,负载均衡等)整合 ...

  3. 【luoguP5490】【模板】扫描线

    求\(n\)个矩形的面积并,可以用线段树维护一条垂直于\(y\)轴的直线上被矩形覆盖的长度有多少长,将直线从左往右扫一遍,遇到矩形左边界就+1,遇到右边界就-1,不为\(0\)的位置就表示没有覆盖 不 ...

  4. 「SDOI2014」旅行(信息学奥赛一本通 1564)(洛谷 3313)

    题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...

  5. 2019蓝桥杯Java第十题大学生B组——最短路径思想

    题目: 代码: package priv.tzk.lanqiao.ten; import java.io.IOException; import java.util.Scanner; public c ...

  6. <每日 1 OJ> -Table

    上图是一个Mysql查询结果图,我们看到这个表格非常漂亮,只需要使用”+”和”-”两个符号就可以打印,现在你的任务是打印一个n×m的表格我们定义单位长度(水平方向有三个”-”,竖直方向有一个”| ”, ...

  7. 大白话说Java反射:入门、使用、原理 (转)

    文章首发于[博客园-陈树义],点击跳转到原文<大白话说Java反射:入门.进阶.原理> 目录 一个简单的例子 反射常用API 获取反射中的Class对象 通过反射创建类对象 通过反射获取类 ...

  8. Net core学习系列(十)——Net Core配置

    一.前言 选项(Options)模式是对配置(Configuration)的功能的延伸.在12章(ASP.NET Core中的配置二)Configuration中有介绍过该功能(绑定到实体类.绑定至对 ...

  9. Ubuntu 14.04下超级终端Minicom连接ARM(转)

    转自:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70209765 笔者的工作环境: PC系统:Ubuntu 14.04 LT ...

  10. Refused to execute script from '...' because its MIME type ('') is not executable, and strict MIME type checking is enabled.

    写在前面 部署项目到weblogic上启动首页访问空白, 浏览器控制台报如题错误. web.xml中把响应头添加防止攻击的报文过滤器禁用就行了(仅仅是为了启动), 以下为转载内容, 可以根据需要自行测 ...