AtCoder Beginner Contest 177 题解

A - Don't be late

问你能不能在时间\(T\)内用不高于\(S\)的速度走过\(D\)的路程,转化为判断\(ST\)不小于\(D\)即可。

#include<bits/stdc++.h>
using namespace std; int d,s,t; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>d>>t>>s;
cout<<(t*s>=d?"Yes":"No"); return 0;
}

B - Substring

给你两个串\(S\)和\(T\),保证\(S\)不短于\(T\),问你在\(S\)中任意截取一个长度和\(T\)相同的字符串,最少要修改多少个字母才能和\(T\)相同。

枚举截取的字符串位置即可。

#include<bits/stdc++.h>
using namespace std; string s,t;
int n,m,a=1e9; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>s>>t;
n=s.size();m=t.size();
for(int i=0;i+m<=n;i++){
int c=0;
for(int j=0;j<m;j++)c+=s[i+j]!=t[j];
a=min(a,c);
}
cout<<a<<endl; return 0;
}

C - Sum of product of pairs

给你一个序列,要求你输出两两相乘的乘积的和。

首先我们固定一个数,可以看出,把它和前面的所有数分别相乘,并把这些乘积加到答案里,就可以不重复的算出答案。根据乘法分配律,这相当于乘上前面所有数的和,然后就可以前缀和优化已经计算过的数的和加速求解。

#include<bits/stdc++.h>
using namespace std; const int mod=1e9+7; int n,a,ans,pre; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n;
for(int i=0;i<n;i++){
cin>>a;
ans=(ans+(long long)pre*a)%mod;
pre=(pre+a)%mod;
}
cout<<ans<<endl; return 0;
}

D - Friends

给你一张无向图,要求划分成一些集合,使得集合内的点两两不能达到。输出最小集合数。

首先可以证明集合数的数量不少于最大的连通块的点的个数,因为每个点需要被单独地划分出来。

然后可以证明这些集合足够存放所有的点,因为不同连通块之内的点可以被放进同一个集合里,因此可以把它们相互独立地考虑。而一个连通块需要的集合数不会超过最大的连通块需要的集合数。

#include<bits/stdc++.h>
using namespace std; int n,m;
vector<int> g[200005];
int sz;
bool vis[200005]; void dfs(int x){
vis[x]=1;
sz++;
for(int &y:g[x])if(!vis[y]){
dfs(y);
}
} int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n>>m;
for(int i=1;i<=m;i++){
static int u,v;
cin>>u>>v;
g[u].emplace_back(v);
g[v].emplace_back(u);
}
int ans=0;
for(int i=1;i<=n;i++)if(!vis[i]){
sz=0;
dfs(i);
ans=max(ans,sz);
}
cout<<ans<<endl; return 0;
}

E - Coprime

给你一个整数序列,判断是否两两互质,整个序列互质(整个序列的公因数为\(1\)),或者不满足先前两种情况。

首先先判断是否整个序列互质,这个单独判断方便一点,就求出整个序列的最大公因数。

那么再判断是否两两互质,我们对每个数分解质因数,记录它包含了哪些质因子(不论那个质因子被乘了多少次)。假如有多于一个的数包含同一个质因子,那么这个序列就不是两两互质的。

#include<bits/stdc++.h>
using namespace std; inline int gcd(int a,int b){
while(b){
a=a%b;
swap(a,b);
}
return a;
} int n,a[1000005],u[1000005]; int main(){ scanf("%d",&n);
int g=0;
for(int i=1;i<=n;i++){
scanf("%d",a+i);
g=gcd(g,a[i]);
for(int j=2;j*j<=a[i];j++){
if(a[i]%j==0){
u[j]++;
while(a[i]%j==0)a[i]/=j;
}
}
u[a[i]]++;
}
if(g>1){
cout<<"not coprime\n";
return 0;
}
for(int i=2;i<=(int)1e6;i++){
if(u[i]>1){
cout<<"setwise coprime\n";
return 0;
}
}
cout<<"pairwise coprime\n"; return 0;
}

F - I hate Shortest Path Problem

给你一个高\(H+1\),宽\(W\)的矩形,第\(i\)行第\(A_i\)个位置到第\(B_i\)个位置下方有挡板,特别地,底部的一行下方没有挡板。

你可以从顶部一行的任意一个位置开始行动,每一步可以向下或向右走一格,要求不能走出矩形或者穿过挡板。问你走到第\(2, 3, \dots, H\)行各最少需要多少步,无法达到输出-1

我们首先需要观察到,除了起始位置的选择不一定尽量靠前外,否则能向下走就直接向下走,不然向右走一格,再尝试向下走,这么持续下去一定是最优的一种考虑。

我们可以模拟走到某一行某一个位置最少需要多少步。此时反向考虑如何走到这个格子。一定是向右移动了某些步数(可能移动零步),然后向下移动一格走到的。向下移动后,我们不需要考虑再向右移动的情况了。因为在转移到下一行时,之前描述的“向右移动了某些步数,然后向下移动一格”包含了这个情况。

它的时间复杂度太大,我们可以考虑使用数据结构来优化。那么此时我们需要分类一下:

  1. 对于上方没有挡板的格子,我们可以直接从上向下转移,假如这个走法不是最优的,可以证明它对答案没有影响。
  2. 对于上方有挡板的格子,直接把它的答案设成正无穷大,因为无法走到。假如这个走法不是最优的,也可以证明它对答案没有影响。
  3. 对于左上方有挡板的格子,可以从上方的格子所有左边的格子转移来。

然后我们就可以使用两棵线段树维护了,假如我们定义当前行的位置\(i\)的答案为\(ans_i\),一棵维护真实的最小值\(ans_i\),一棵维护\(ans_i+W-i\),用于做第三种更新。需要先做第三种更新,因为我们此时的转移都做在同一个线段树内,顺序会相互影响。

#include<bits/stdc++.h>
using namespace std; struct SegTree{ int sz;
vector<long long> dat,laz; SegTree(){
sz=1<<18;
dat.resize(sz<<1);
laz.resize(sz<<1);
}; void upd(int id,int l,int r,int ql,int qr,long long val){
if(qr<l||r<ql)return;
if(ql<=l&&r<=qr){
laz[id]+=val;
dat[id]+=val;
return;
}
laz[id<<1]+=laz[id];
dat[id<<1]+=laz[id];
laz[id<<1|1]+=laz[id];
dat[id<<1|1]+=laz[id];
laz[id]=0;
upd(id<<1,l,l+r>>1,ql,qr,val);
upd(id<<1|1,(l+r>>1)+1,r,ql,qr,val);
dat[id]=min(dat[id<<1],dat[id<<1|1]);
} long long qry(int id,int l,int r,int ql,int qr){
if(qr<l||r<ql)return 1e18;
if(ql<=l&&r<=qr){
return dat[id];
}
laz[id<<1]+=laz[id];
dat[id<<1]+=laz[id];
laz[id<<1|1]+=laz[id];
dat[id<<1|1]+=laz[id];
laz[id]=0;
return min(qry(id<<1,l,l+r>>1,ql,qr),qry(id<<1|1,(l+r>>1)+1,r,ql,qr));
} void upd(int l,int r,long long d){
upd(1,1,sz,l,r,d);
} long long qry(int l,int r){
return qry(1,1,sz,l,r);
}
}; int n,m;
int a[200005],b[200005];
SegTree upd,qry; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n>>m;
for(int i=1;i<=m;i++)upd.upd(i,i,m-i);
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
qry.upd(b[i]+1,b[i]+1,min(upd.qry(1,b[i])-(m-b[i]-1)-qry.qry(b[i]+1,b[i]+1),0ll));
upd.upd(b[i]+1,b[i]+1,min(upd.qry(1,b[i])-upd.qry(b[i]+1,b[i]+1),0ll));
qry.upd(a[i],b[i],1e9);
upd.upd(a[i],b[i],1e9);
qry.upd(1,m,1);
upd.upd(1,m,1);
if(qry.qry(1,m)>=1e9)cout<<"-1\n";
else cout<<qry.qry(1,m)<<'\n';
} return 0;
}

AtCoder Beginner Contest 177 题解的更多相关文章

  1. AtCoder Beginner Contest 154 题解

    人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...

  2. AtCoder Beginner Contest 153 题解

    目录 AtCoder Beginner Contest 153 题解 A - Serval vs Monster 题意 做法 程序 B - Common Raccoon vs Monster 题意 做 ...

  3. AtCoder Beginner Contest 184 题解

    AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...

  4. AtCoder Beginner Contest 173 题解

    AtCoder Beginner Contest 173 题解 目录 AtCoder Beginner Contest 173 题解 A - Payment B - Judge Status Summ ...

  5. AtCoder Beginner Contest 172 题解

    AtCoder Beginner Contest 172 题解 目录 AtCoder Beginner Contest 172 题解 A - Calc B - Minor Change C - Tsu ...

  6. AtCoder Beginner Contest 169 题解

    AtCoder Beginner Contest 169 题解 这场比赛比较简单,证明我没有咕咕咕的时候到了! A - Multiplication 1 没什么好说的,直接读入两个数输出乘积就好了. ...

  7. AtCoder Beginner Contest 148 题解

    目录 AtCoder Beginner Contest 148 题解 前言 A - Round One 题意 做法 程序 B - Strings with the Same Length 题意 做法 ...

  8. AtCoder Beginner Contest 151 题解报告

    总的来说,这次的题目比较水,然而菜菜的我并没有把所有题目都做完,话不多说,直接来干货: A:Next Alphabet 题目链接:https://atcoder.jp/contests/abc151/ ...

  9. AtCoder Beginner Contest 115 题解

    题目链接:https://abc115.contest.atcoder.jp/ A Christmas Eve Eve Eve 题目: Time limit : 2sec / Memory limit ...

随机推荐

  1. PHP boolval() 函数

    boolval 函数用于获取变量的布尔值.高佣联盟 www.cgewang.com 版本要求:PHP 5 >= 5.5.0, PHP 7. 语法 boolean boolval ( mixed ...

  2. qt事件过滤器的使用(可以用于控制屏幕背光等)

    在嵌入式qt项目中,有时并不需求屏幕一直亮着,需要一段时间不操作时,将屏幕背光关掉,以达到节能的目的: 在qt项目中,可以通过重写事件过滤器来实现屏幕操作的检测,加上定时器的时间控制,可以实现指定时间 ...

  3. Prometheus监控神器-Alertmanager篇(1)

    本章节主要涵盖了Alertmanager的工作机制与配置文件的比较详细的知识内容,由浅入深的给大家讲解. 警报一直是整个监控系统中的重要组成部分,Prometheus监控系统中,采集与警报是分离的.警 ...

  4. 谈谈集成测试(integration testing)

    对于软件开发来说,软件测试是一个几乎贯穿所有阶段的活动,所以测试的重要性毋庸置疑.不同开发组织如何在不同的产品研发阶段进行测试,也在很大程度上反映了其研发能力和质量控制能力.软件测试有很多类型,包括单 ...

  5. C#LeetCode刷题之#11-盛最多水的容器(Container With Most Water)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3615 访问. 给定 n 个非负整数 a1,a2,...,an,每 ...

  6. GitHub 热点速览 Vol.32:VScode 韭菜基金插件,极大提高“工作”效率

    作者:HelloGitHub-小鱼干 摘要:有什么比干着本职工作--编码,而又兼顾"外快"--炒股更有开心的事情呢?leek-fund 就是这么一个极大提升你工作幸福度和效率的插件 ...

  7. 编译原理 First集和Follow集的求法

    转载地址 https://blog.csdn.net/Alexander_Frank/article/details/51280798 自上而下分析: FIRST集求法 First集合最终是对产生式右 ...

  8. JMeter软件测试工具介绍及基本安装教程

    一.工具介绍 (一)简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试 ...

  9. CheckList:ACL 2020 Best Paper

    Beyond Accuracy: Behavior Testing of NLP Models with CheckList. Marco Tulio Ribeiro, Tongshuang Wu, ...

  10. 《JavaScript语言入门教程》记录整理:面向对象

    目录 面向对象编程 实例对象与 new 命令 this关键字 对象的继承 Object对象的方法 严格模式(strict mode) 本系列基于阮一峰老师的<JavaScrip语言入门教程> ...