Codeforces Round #513 by Barcelona Bootcamp
A. Phone Numbers
签.
#include <bits/stdc++.h>
using namespace std; #define N 110
char s[N];
int cnt[], n; int main()
{
while (scanf("%d", &n) != EOF)
{
scanf("%s", s + );
memset(cnt, , sizeof cnt);
for (int i = ; i <= n; ++i)
++cnt[s[i] - ''];
int res = ;
for (int i = ; i <= cnt[]; ++i)
res = max(res, min(i, (n - i) / ));
printf("%d\n", res);
}
return ;
}
B. Maximum Sum of Digits
Solved.
题意:
将一个数拆成$a + b = n$
$要求S(a) + S(b)最大$
$定义S(x) 为x的各位数字之和(以十进制表示)$
思路:
贪心构造一个数字$a有尽量多的9并且小于n即可$
$为什么这样是对的$
我们假设最优解为$a, b$
$令a_i, b_i表示a, b的第i位$
$如果存在某个a_i,不是9, 那么我们将它改成9$
$那么对b_i的影响就是要减去差值$
$如果造成退位,那么答案更优$
$如果没有退位,那么答案不变$
#include <bits/stdc++.h>
using namespace std; #define ll long long
ll n; int f(ll x)
{
int res = ;
while (x)
{
res += x % ;
x /= ;
}
return res;
} int main()
{
while (scanf("%lld", &n) != EOF)
{
int res = ;
if (n <= )
{
for (int i = ; i <= n; ++i)
res = max(res, f(i) + f(n - i));
}
else
{
ll tmp = n;
string s = "";
while (tmp)
{
if (tmp / ) s += '';
else if (tmp > ) s += tmp - + '';
tmp /= ;
}
ll x = ;
reverse(s.begin(), s.end());
for (int i = , len = s.size(); i < len; ++i) x = x * + s[i] - '';
res = f(x) + f(n - x);
ll mid = n / ;
for (ll i = max(0ll, mid - ); i <= min(n, mid + ); ++i)
res = max(res, f(i) + f(n - i));
}
printf("%d\n", res);
}
return ;
}
C. Maximum Subrectangle
Solved.
题意:
有一个矩阵$c_{i, j} = a_i \cdot b_j$
$求一个最大子矩阵使得\sum\limits_{i = x_1}^{x_2} \sum\limits_{i = y_1}^{y_2} c_{i, j} <= x$
思路:
我们考虑将求和的式子变换一下
$\sum\limits_{i = x_1}^{x_2} \sum\limits_{i = y_1}^{y_2} c_{i, j} = $
$\sum\limits_{i = x_1}^{x_2} \sum\limits_{i = y_1}^{y_2} a_i \cdot b_j = $
$\sum\limits_{i = x_1}^{x_2} a_i \cdot \sum\limits_{i = y_1}^{y_2} b_j $
那么我们要想使面积最大
只要先预处理出长度为$x的子段和最小的a[] 和 长度为y的字段和最小的b[]$
$再枚举x, y更新答案即可$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 2010
int n, m, a[N], b[N];
ll x;
int f[N], g[N]; int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", a + i), a[i] += a[i - ];
for (int i = ; i <= m; ++i) scanf("%d", b + i), b[i] += b[i - ];
scanf("%lld", &x);
memset(f, 0x3f, sizeof f);
memset(g, 0x3f, sizeof g);
for (int i = ; i <= n; ++i)
for (int j = i; j <= n; ++j)
f[j - i + ] = min(f[j - i + ], a[j] - a[i - ]);
for (int i = ; i <= m; ++i)
for (int j = i; j <= m; ++j)
g[j - i + ] = min(g[j - i + ], b[j] - b[i - ]);
int res = ;
for (int i = ; i <= n; ++i)
for (int j = ; j <= m; ++j)
if (1ll * f[i] * g[j] <= x)
res = max(res, i * j);
printf("%d\n", res);
}
return ;
}
D. Social Circles
Solved.
题意:
有$n个人,要坐在若干个圆桌上,每个人要求左边和右边至少有l_i 和r_i个空凳子$
$空凳子部分可以交叉$
至少需要几张凳子
思路:
我们考虑答案就是$\sum l_i + \sum r_i + n - 交叉部分$
$那么我们就是尽量让交叉部分大即可$
$那么右边空凳子需求多的要和左边空凳子需求多的相邻即可$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
int n;
int l[N], r[N]; int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d%d", l + i, r + i);
sort(l + , l + + n);
sort(r + , r + + n);
ll res = ;
for (int i = ; i <= n; ++i) res += max(l[i], r[i]);
printf("%lld\n", res + n);
}
return ;
}
E. Sergey and Subway
Solved.
题意:
给出一棵树
$现在如果有两个点共同邻接另外一个点$
$那么就给这两个点连一条边$
求新图中所有点对之间的最短距离
思路:
我们考虑新图中两点之间距离和原图之间的关系
$我们考虑下面这样的$
$1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8$
$我们用dis[x] 表示x -> 1的距离$
$在原图中$
$dis_2 = 1, dis_3 = 2, dis_4 = 3, dis_5 = 4, dis_6 = 5, dis_7 = 6, dis_8 = 7$
在新图中
$dis_2 = 1, dis_3 = 1, dis_4 = 2, dis_5 = 2, dis_6 = 3, dis_7 = 3, dis_8 = 4$
$我们发现新图和原图中距离的关系是$
$dis_新 = (dis_原 + 1) / 2$
$用线段树维护原图距离以及奇数个数再树形dp即可$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 200010
int n;
vector <int> G[N]; namespace SEG
{
struct node
{
ll a, b, lazy, cnt;
void init()
{
a = b = lazy = cnt = ;
}
void add(ll x)
{
a += x * cnt;
lazy += x;
if (abs(x) % )
b = cnt - b;
}
ll f()
{
return (a + b) / ;
}
node operator + (const node &other) const
{
node res; res.init();
res.a = a + other.a;
res.b = b + other.b;
res.cnt = cnt + other.cnt;
return res;
}
}a[N << ];
void build(int id, int l, int r)
{
a[id].init();
a[id].cnt = r - l + ;
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
}
void pushdown(int id)
{
if (!a[id].lazy) return;
a[id << ].add(a[id].lazy);
a[id << | ].add(a[id].lazy);
a[id].lazy = ;
}
void update(int id, int l, int r, int ql, int qr, int val)
{
if (l >= ql && r <= qr)
{
a[id].add(val);
return;
}
int mid = (l + r) >> ;
pushdown(id);
if (ql <= mid) update(id << , l, mid, ql, qr, val);
if (qr > mid) update(id << | , mid + , r, ql, qr, val);
a[id] = a[id << ] + a[id << | ];
}
} int fa[N], deep[N], in[N], out[N], cnt;
void DFS(int u)
{
in[u] = ++cnt;
for (auto v : G[u]) if (v != fa[u])
{
fa[v] = u;
deep[v] = deep[u] + ;
DFS(v);
}
out[u] = cnt;
} ll res;
void DFS2(int u)
{
res += SEG::a[].f();
for (auto v : G[u]) if (v != fa[u])
{
SEG::update(, , n, , n, );
SEG::update(, , n, in[v], out[v], -);
DFS2(v);
SEG::update(, , n, , n, -);
SEG::update(, , n, in[v], out[v], );
}
}
int main()
{
while (scanf("%d", &n) != EOF)
{
cnt = ; res = ;
for (int i = ; i <= n; ++i) G[i].clear();
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
deep[] = ;
DFS();
SEG::build(, , n);
for (int i = ; i <= n; ++i) SEG::update(, , n, in[i], in[i], deep[i]);
DFS2();
printf("%lld\n", res / );
}
return ;
}
Codeforces Round #513 by Barcelona Bootcamp的更多相关文章
- Codeforces Round #513 by Barcelona Bootcamp C. Maximum Subrectangle(双指针+思维)
https://codeforces.com/contest/1060/problem/C 题意 给两个数组,a数组有n个元素,b数组有m个元素,两个数组元素互相相乘形成n*m的矩阵,找一个子矩阵,元 ...
- Codeforces Round #513 by Barcelona Bootcamp (rated, Div. 1 + Div. 2) C D
C - Maximum Subrectangle 因为是两个数组相乘的到的 矩阵所以 a(i ->j)*b(x->y) 的面积 就是 a(i ->j) 的和乘与b(x-> ...
- [Codeforces Round #513 by Barcelona Bootcamp (rated, Div. 1 + Div. 2) ](A~E)
A: 题目大意:给你一个数字串,每个数字只可以用一次,求最多可以组成多少个电话号码(可以相同),电话号码第一个数字为$8$,且长度为$11$ 题解:限制为$8$的个数和总长度,直接求 卡点:无 C++ ...
- Codeforces Round #513 游记
Codeforces Round #513 游记 A - Phone Numbers 题目大意: 电话号码是8开头的\(1\)位数字.告诉你\(n(n\le100)\)个数字,每个数字至多使用一次.问 ...
- Codeforces Round #513 总结
首次正式的$Codeforces$比赛啊,虽然滚粗了,然而终于有$rating$了…… #A Phone Numbers 签到题,然而我第一次写挂了(因为把11看成8了……) 只需要判断一下有多少个 ...
- Codeforces Round #513解题报告(A~E)By cellur925
我是比赛地址 A:Phone Numbers $Description$:给你一串数字,问你能组成多少开头为8的11位电话号码. $Sol$:统计8的数量,与$n$%11作比较. #include&l ...
- Codeforces Round #513
A. Phone Numbers 题意:给一些数字,每个电话号码以8开头,11位,求最多组成多少个号码,重复累加. #include <bits/stdc++.h> using names ...
- Codeforces Round 513 (Div.1+Div.2)
比赛传送门 10月4号的比赛,因为各种原因(主要是懒),今天才写总结-- Div1+Div2,只做出两个题+迟到\(20min\),日常掉\(rating\)-- \(\rm{A.Phone\;Num ...
- Codeforces Round #513 (rated, Div. 1 + Div. 2)
前记 眼看他起高楼:眼看他宴宾客:眼看他楼坍了. 比赛历程 开考前一分钟还在慌里慌张地订正上午考试题目. “诶这个数位dp哪里见了鬼了???”瞥了眼时间,无奈而迅速地关去所有其他窗口,临时打了一个缺省 ...
随机推荐
- List自定义排序
List自定义排序我习惯根据Collections.sort重载方法来实现,下面我只实现自己习惯方式.还有一种就是实现Comparable接口. 挺简单的,直接上代码吧. package com.so ...
- Keil(MDK-ARM)在线调试(Ⅰ)(转)
Ⅰ.写在前面 Keil在线调试的内容有很多,本文带来在线调试常用的内容:Debug Toolbar调试工具栏(复位.全速运行.停止运行.单步调试.逐行调试.跳出调试.运行到光标行.跳转到暂停行.调试窗 ...
- CocoaPods的 安装 /卸载/升级
CocoaPods用来管理第三方框架 Mac 安装 Cocoapods 导引如果你的 Mac OSX 升级到 10.11.x+, 并且需要安装 Cocoapods, 可以参考本博客.安装 rubyMa ...
- MySQL查询语句练习题
1.创建student和score表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARC ...
- OLE工具套件分析OFFICE宏恶意样本
零.绪论:OLE工具套件的介绍 OLE工具套件是一款针对OFFICE文档开发的具有强大分析功能一组工具集.这里主要介绍基于Python2.7的OLEtools的安装和使用. (1)Python版本需求 ...
- 日志记录---log4j详解
Apache官方项目地址 通常的日志记录的缺点是会减慢程序的运行速度,如果用普通的System.out的话影响视觉效果,另外解耦度也不好,而log4j的设计则使得日志记录变得可靠快速和可拓展性好. l ...
- 详解Go语言中的屏蔽现象
在刚开始学习Go语言的过程中,难免会遇到一些问题,尤其是从其他语言转向Go开发的人员,面对语法及其内部实现的差异,在使用Go开发时也避免不了会踩"坑".本文主要针对Go设计中的屏蔽 ...
- 强连通分量+缩点(poj2553)
http://poj.org/problem?id=2553 The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total ...
- JavaCSV之读CSV文件
Java在进行数据处理,有时候难免有进行CSV文件的操作,这里采用了JavaCSV读CSV文件. 1.准备工作 (1)第三方包库下载地址:https://sourceforge.net/project ...
- go 工具链目前[不支持编译 windows 下的动态链接库]解决方案
go 工具链目前[不支持编译 windows 下的动态链接库][1],不过[支持静态链接库][2].想要产生dll,可以这样 workaround ,参考 golang [issuse#11058][ ...