Codeforces Round #513 游记

A - Phone Numbers

题目大意:

电话号码是8开头的\(1\)位数字。告诉你\(n(n\le100)\)个数字,每个数字至多使用一次。问最多能凑出多少个电话号码。

思路:

统计8出现的次数,如果有多余的8不能作为开头,那么就将其放到后面去

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
inline int getdigit() {
register char ch;
while(!isdigit(ch=getchar()));
return ch^'0';
}
int cnt[2];
int main() {
const int n=getint();
for(register int i=0;i<n;i++) cnt[getdigit()==8]++;
while(cnt[0]<cnt[1]*10) {
cnt[1]--;
cnt[0]++;
}
printf("%d\n",std::min(cnt[1],cnt[0]/10));
return 0;
}

B - Maximum Sum of Digits

题目大意:

定义\(S(x)\)为\(x\)各数位之和。给定\(n(n\le10^{12})\),\(a+b=n\),求\(S(a)+S(b)\)的最大值。

思路:

如果这一位\(x\)不是第一位,且这一位不是\(9\),就把这一位当做\(10+x\),并把上一位\(-1\)。

源代码:


#include<cstdio>
#include<cctype>
typedef long long int64;
inline int64 getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int64 x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
int main() {
int64 n=getint();
int ans=0;
for(;n;n/=10) {
ans+=n%10;
if(n%10!=9&&n/10!=0) {
ans+=10;
n-=10;
}
}
printf("%d\n",ans);
return 0;
}

C - Maximum Subrectangle

题目大意:

给定\(a_{1\sim n},b_{1\sim m}(n,m\le2000)\)和\(x\),\(c_{i,j}=a_ib_j\)。求\(c\)的一个最大子矩阵,使得矩阵内数字和\(\le x\)。输出面积的最大值。

思路:

预处理\(a/b\)连续\(i\)个数之和的最小值。然后枚举矩形长宽即可。

源代码:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=2001;
int a[N],b[N],min1[N],min2[N];
int main() {
const int n=getint(),m=getint();
for(register int i=1;i<=n;i++) a[i]=getint();
for(register int i=1;i<=m;i++) b[i]=getint();
const int x=getint();
for(register int i=1;i<=n;i++) {
min1[i]=INT_MAX;
int sum=0;
for(register int j=1;j<i;j++) sum+=a[j];
for(register int j=i;j<=n;j++) {
sum-=a[j-i];
sum+=a[j];
min1[i]=std::min(min1[i],sum);
}
}
for(register int i=1;i<=m;i++) {
min2[i]=INT_MAX;
int sum=0;
for(register int j=1;j<i;j++) sum+=b[j];
for(register int j=i;j<=m;j++) {
sum-=b[j-i];
sum+=b[j];
min2[i]=std::min(min2[i],sum);
}
}
int ans=0;
for(register int i=1;i<=n;i++) {
for(register int j=1;j<=m;j++) {
if((int64)min1[i]*min2[j]<=x) {
ans=std::max(ans,i*j);
}
}
}
printf("%d\n",ans);
return 0;
}

D - Social Circles

题目大意:

有\(n(n\le10^5)\)个人排成一圈,第\(i\)个人要求自己左边空出\(l_i\)个座位,右边空出\(r_i(l_i,r_i\le10^9)\)个座位。问最少需要安排多少个座位。

思路:

一开始先假设每个人都占了\(l_i+r_i+1\)个位置。考虑怎样安排相邻人的顺序,并合并相邻人的\(l_i,r_i\)使得答案最优。

将所有\(l_i,r_i\)分别排序,将对应的\(l_i,r_i\)合并一定是最优的(想一想这是为什么)。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=1e5+1;
int l[N],r[N];
int main() {
const int n=getint();
int64 ans=0;
for(register int i=1;i<=n;i++) {
l[i]=getint();
r[i]=getint();
ans+=l[i]+r[i]+1;
}
std::sort(&l[1],&l[n]+1);
std::sort(&r[1],&r[n]+1);
for(register int i=1;i<=n;i++) {
ans-=std::min(l[i],r[i]);
}
printf("%lld\n",ans);
return 0;
}

E - Sergey and Subway

题目大意:

给定一棵\(n(n\le2\times10^5)\)个点的树,每条边权都是\(1\)。原树上的边称作老边,两个点之间可以连一条新边当且仅当原来两个点之间距离为\(2\)。问最后所有点对之间最短路之和是多少?

思路:

首先不考虑新边,我们可以考虑每条边的贡献计算出所有点对距离值和\(sum\)。

而经过加新边的操作后,原来距离为偶数的点对距离\(/2\),奇数点对距离\(/2+1\)。而我们可以通过黑白染色后黑/白点的数目统计出奇数距离的点对数目。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
using int64=long long;
const int N=2e5+1;
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
int64 ans;
bool col[N];
int n,size[N],cnt[2],par[N];
void dfs(const int &x,const int &par) {
size[x]=1;
::par[x]=par;
cnt[col[x]=!col[par]]++;
for(auto &y:e[x]) {
if(y==par) continue;
dfs(y,x);
size[x]+=size[y];
ans+=(int64)size[y]*(n-size[y]);
}
}
int main() {
n=getint();
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
dfs(1,0);
ans=(ans+(int64)cnt[0]*cnt[1])/2;
printf("%lld\n",ans);
return 0;
}

Codeforces Round #513 游记的更多相关文章

  1. Codeforces Round #513 总结

    首次正式的$Codeforces$比赛啊,虽然滚粗了,然而终于有$rating$了…… #A  Phone Numbers 签到题,然而我第一次写挂了(因为把11看成8了……) 只需要判断一下有多少个 ...

  2. Codeforces Round #513 by Barcelona Bootcamp C. Maximum Subrectangle(双指针+思维)

    https://codeforces.com/contest/1060/problem/C 题意 给两个数组,a数组有n个元素,b数组有m个元素,两个数组元素互相相乘形成n*m的矩阵,找一个子矩阵,元 ...

  3. Codeforces Round #513解题报告(A~E)By cellur925

    我是比赛地址 A:Phone Numbers $Description$:给你一串数字,问你能组成多少开头为8的11位电话号码. $Sol$:统计8的数量,与$n$%11作比较. #include&l ...

  4. 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-> ...

  5. Codeforces Round #513 by Barcelona Bootcamp

    A. Phone Numbers 签. #include <bits/stdc++.h> using namespace std; #define N 110 char s[N]; ], ...

  6. Codeforces Round #513

    A. Phone Numbers 题意:给一些数字,每个电话号码以8开头,11位,求最多组成多少个号码,重复累加. #include <bits/stdc++.h> using names ...

  7. [Codeforces Round #513 by Barcelona Bootcamp (rated, Div. 1 + Div. 2) ](A~E)

    A: 题目大意:给你一个数字串,每个数字只可以用一次,求最多可以组成多少个电话号码(可以相同),电话号码第一个数字为$8$,且长度为$11$ 题解:限制为$8$的个数和总长度,直接求 卡点:无 C++ ...

  8. Codeforces Round 513 (Div.1+Div.2)

    比赛传送门 10月4号的比赛,因为各种原因(主要是懒),今天才写总结-- Div1+Div2,只做出两个题+迟到\(20min\),日常掉\(rating\)-- \(\rm{A.Phone\;Num ...

  9. Codeforces Round #513 (rated, Div. 1 + Div. 2)

    前记 眼看他起高楼:眼看他宴宾客:眼看他楼坍了. 比赛历程 开考前一分钟还在慌里慌张地订正上午考试题目. “诶这个数位dp哪里见了鬼了???”瞥了眼时间,无奈而迅速地关去所有其他窗口,临时打了一个缺省 ...

随机推荐

  1. 【vim】查找重复的连续的单词

    当你很快地打字时,很有可能会连续输入同一个单词两次,就像 this this.这种错误可能骗过任何一个人,即使是你自己重新阅读一遍也不可避免.幸运的是,有一个简单的正则表达式可以用来预防这个错误.使用 ...

  2. centos6.5 nfs实时共享

    一.什么时NFS NFS(Network File System)——网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,NF ...

  3. SharePoint 2010 使用Install-SPSolution部署wsp包状态一直是”正在部署”

    1.服务器场信息如下: 2.使用下面命令部署,状态一直是"正在部署" Install-SPSolution –Identity xxxx.wsp –WebApplication h ...

  4. 带你玩转Visual Studio——带你理解微软的预编译头技术

    原文地址:http://blog.csdn.net/luoweifu/article/details/49010627 不陌生的stdafx.h 还记得带你玩转Visual Studio——带你新建一 ...

  5. 一步步实现windows版ijkplayer系列文章之六——SDL2源码分析之OpenGL ES在windows上的渲染过程

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  6. 解决报错error the @annotation pointcut expression is only supported at Java 5

    eclipse搭建环境后报错 error the @annotation pointcut expression is only supported at Java 5 错误意思大致是:注释切入点表达 ...

  7. Spring MVC注解配置

    http://blog.csdn.net/eventys/article/details/8208808

  8. python语法小应用---列表和元组

    声明:本文章为参考总结CSDN上知识点所获,只是用来总结自己学习而用,如有侵权,会删除! 列表(list): 列表就像一个线性容器,但是比C++的 lis t扩展多得多 列表里的元素可以是相同类型,也 ...

  9. HDU 5288 OO&rsquo;s Sequence

    题意: 给你一个序列, 有一个函数 F(L,R) 其中 ai 均不能 被 aL - aR整除的  函数值是这个ai个数 思路 : 反过来求 满足这样的条件的 ai 的区间,然后求和 #include& ...

  10. visual studio 2017 installer 安装包制作过程出现的问题---此安装程序需要.NET Framework 版本 3.5,请安装该版本,然后重新运行此安装程序,可以从Web获得.NET Framework 。要立即做此事吗?

    图一 visual studio 2017 installer 打包完成以后进行安装时,提示信息 “安装此安装程序需要.NET Framework 版本 3.5,请安装该版本,然后重新运行此安装程序, ...