Codeforces Round #613 (Div. 2) A-E简要题解
contest链接:https://codeforces.com/contest/1285
A. Mezo Playing Zoma
签到
#include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
const int maxn = ;
typedef long long ll;
queue<pair<int,int> > q;
map<int,bool> vis;
vector<int> v;
/*
1111111111111111111111111111111111111
*/
int a[maxn];
int main()
{
int n;
cin>>n;
string s;
cin>>s;
int n1=,n2=;
for(int i=;i<s.size();i++)
{
if(s[i]=='L')
n1++;
if(s[i]=='R')
n2++;
}
cout<<n2+n1+;
return ;
}
B. Just Eat It!
#include <bits/stdc++.h>
using namespace std;
#define finish(x) return cout << x << endl, 0
#define ll long long int n;
vector <int> a; bool solve(){
cin >> n;
a.resize(n);
for(auto &i : a) cin >> i;
ll sum = ;
for(int i = ; i < n ; i++){
sum += a[i];
if(sum <= ) return ;
}
sum = ;
for(int i = n - ; i >= ; i--){
sum += a[i];
if(sum <= ) return ;
}
return ;
}
int main(){
ios_base::sync_with_stdio();
cin.tie();
int T;
cin >> T;
while(T--){
if(solve()) cout << "YES\n";
else cout << "NO\n";
}
}
C. Fadi and LCM
题意:给一个整数X(1~10^12),找到两个数a,b,使得LCM(a,b) = X,且max(a,b)尽可能地小。
思路:LCM(a,b) = X,则a,b必是X的因子,那么对于X,除去他自己本身,最大的因子不会超过√x,且对于X始终会存在一对a,b互素,LCM(a,b) = X。所以枚举a从√x开始,如果再计算n/a = b,若gcd(a,b) = 1,则就是使得max(a,b)尽可能小的答案了。
AC:
#include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
const int maxn = ;
typedef long long ll;
ll gcd(ll a, ll b){ return b?gcd(b,a%b):a; }
ll lcm(ll a, ll b){ return a/gcd(a,b)*b; }
vector<ll> v1;
int main()
{
ll a,b;
ll n;
cin>>n;
for(int i = sqrt(n);i>=;i--){
if(n%i == ){
if(gcd(i,n/i) == ){
cout<<i<<" "<<n/i;
return ;
}
}
}
cout<<<<" "<<n;
return ;
}
D. Dr. Evil Underscores
题意:给n个数a1,a2,a3.....an,找到一个数X,使得X 异或所有的ai ,得到的max(X xor ai)最小,输出这个值。
思路:a的范围是0~230,我们可以以01二进制的形式建一棵深度为30的字典树,每个数ai 的二进制序列插入到字典树中去,例如5 = 101,那么101按位插入到字典树中去。然后从根开始遍历,在字典树上dp,因为该字典树建完后是一棵二叉树,所以分支情况就两种,下一位是0或1,那么如果只遇到1就往1这个分支走,这一位便没有贡献,如果只遇到0就往0这个分支走,这一位也没有贡献,如果遇到的是0和1两个分支,那么必定要加上这一位的贡献,然后递归01两个分支,两者再去min,一直递归到最后一位。
AC代码:
#include<iostream>
#include<vector>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
int trie[][],cnt ;
//bool exist[31*31];// 该结点结尾的字符串是否存在
void insert(int a){//建trie树
int p = ;
for(int i = ;i>=;i--){
int c = (a>>i)&;
if(!trie[p][c]) trie[p][c] = ++cnt; // 如果没有,就添加结点
p = trie[p][c];
}
// exist[p] = 1;
}
ll solve(ll cur,int k){
if(k == -) return ;
if(trie[cur][] == ){
return solve(trie[cur][],k-);//如果只有1分支
}
else if(trie[cur][] == ){//如果只有0分支
return solve(trie[cur][],k-);
}
else{
return (<<k)+min(solve(trie[cur][],k-),solve(trie[cur][],k-));//0 1分支都有的情况
}
}
int main()
{
int n;
cin>>n;
for(int i = ;i<n;i++){
ll a;cin>>a;
insert(a);
}
ll ans = solve(,);
cout<<ans;
return ;
}
E. Delete a Segment
题意:给一个数轴上有n个线段集,线段集若有相交,则合并为一个新的合并线段集,比如[1,6]和[2,9],因为两个线段有相交,所以要合并为[1,9],先问删掉给定的n个线段集中的任意一个,剩下的n-1个线段组成的新的合并线段集数量最大是多少?
思路:
这道题首先想到的是并查集做法,枚举删除任意一条线段后,剩下的线段组成的集合是多少,取max,这个复杂度有n2 × 并查集复杂度,显然是不行的。那么考虑离散化处理线段左右端点,然后去扫描。

如图所示,线段1,2,3,4离散化处理左右端点,然后排个序并标记一下线段号,开始扫描,扫描到的端点先放入multiset集合中去,最初扫描到线段1的左端点L1,然后是L2,再然后是R1,此时我们发现,线段1已经扫描完比,那么删除这条线段1的左右端点,发现集合中只剩下了L2,且下一个要扫描到的端点是L3,此时就意味着删除点线段2后,线段1和线段3是不相交的,那么删除线段2后,新线段合并集合数量就会+1。同理当扫描到R2时,整个线段2已经扫描完毕,删除集合中线段2左右端点,集合只剩下线段3的左端点,且下一个元素是线段4的左端点,说明线段2和线段4不相交,那么此时删除线段3,就意味着线段2和线段4不相连,新线段合并集合数量就+1,根据以上这个性质,扫描的时候枚举下个元素是左端点还是右端点,记录删除每个线段删除后,合并集合会增加多少,最终拿最初不删除任何线段得到的合并线段集数量+max(删除某一线段增加的数量)就是答案
当然要特判一种情况:

如图所示线段1这种情况,删除这条线段,则新合并集是-1,因为它没有和任何线段有相交,本身就构成一个独立的合并线段集,删除就减少1个合并线段集,特判这种情况即可。
AC代码:
#include<iostream>
#include<vector>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 4e5+;
pair<ll,ll> p[maxn];
int cnt[maxn];
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i = ;i<=n;i++){
ll l,r;
cin>>l>>r;
p[*i-] = make_pair(l,-i);//离散化记录区间左右端点的位置和区间标号i
p[*i] = make_pair(r,i);
cnt[i] = ;
}
sort(p+,p+*n+);
int ans = ;
multiset<int> s;
for(int i = ;i<=*n;i++){
if(p[i].second < ){//如果是左端点,就插入set
s.insert(-p[i].second );
}
else{
s.erase(s.find(p[i].second));//如果是右端点,就把这个区间删除
}
if(s.size() == ) ans++;//如果集合是空,记录一个合并的区间
if(s.size() == && p[i].second > && p[i+].second < && p[i+].first > p[i].first ){
cnt[*s.begin()]++;//当前是左端点,但是下个是右端点,cnt++
}
if(s.size() == && p[i].second < && p[i+].second >){
cnt[*s.begin()]--;//特判,如果首先插入地是一段单独区间(l r),去掉这个区间则区间数量-1
}
}
int t = -;
for(int i = ;i<=n;i++){
t = max(t,cnt[i]);
}
cout<<ans+t<<endl;
}
return ;
}
Codeforces Round #613 (Div. 2) A-E简要题解的更多相关文章
- Codeforces Round #609 (Div. 2)前五题题解
Codeforces Round #609 (Div. 2)前五题题解 补题补题…… C题写挂了好几个次,最后一题看了好久题解才懂……我太迟钝了…… 然后因为longlong调了半个小时…… A.Eq ...
- Codeforces Round #613 Div.1 D.Kingdom and its Cities 贪心+虚树
题目链接:http://codeforces.com/contest/613/problem/D 题意概述: 给出一棵树,每次询问一些点,计算最少删除几个点可以让询问的点两两不连通,无解输出-1.保证 ...
- Codeforces Round #613 (Div. 2) (A-E)
A略 直接求和最大的子序列即可(注意不能全部选中整个子序列) or #include<bits/stdc++.h> using namespace std; void solve(){ i ...
- Codeforces Round #613 (Div. 2)D(贪心,分治)
构造两颗深度为30的字典树(根节点分别是0和1),结点只有0和1,从根节点向下DFS,贪心取答案. #define HAVE_STRUCT_TIMESPEC #include<bits/stdc ...
- Codeforces Round #613 (Div. 2) C. Fadi and LCM(LCM & GCD)
题意: LCM(a, b) = X,求 max(a, b) 的最小值. 思路: a, b 只可能存在于 X 的因子中,枚举即可. #include <bits/stdc++.h> usin ...
- Codeforces Round #613 (Div. 2) B. Just Eat It!(前缀和)
题意: 一个长为n的序列,是否存在与原序列不同的连续子序列,其元素之和大于等于原序列. 思路: 从前.后分别累加,若出现非正和,除此累加序列外的子序列元素之和一定大于等于原序列. #include & ...
- Codeforces Round #613 (Div. 2) A. Mezo Playing Zoma(逻辑)
题意: 给出一个移动序列,可以无效化一些指令,问可以移动到多少不同位置. 思路: 第一印象是统计左右指令数目,后来发现左右指令数目和即字符串长度. #include <bits/stdc++.h ...
- Codeforces Round #613 (Div. 2) C. Fadi and LCM (数学)
题意:给你一个正整数\(x\),找两个正整数\(a\),\(b\),使得\(lcm(a,b)=x\),并且\(max(a,b)\)最小. 题解:我们知道,\(lcm(a,b)=a*b/gcd(a,b) ...
- Codeforces Round #613 (Div. 2) B. Just Eat It! (DP)
题意:有一个长度为\(n\)的序列,找出最大的长度不为\(n\)的子段和,问最大子段和是否小于所有元素和. 题解:最大子段和我们可以直接用dp来找,每次状态转移为:\(dp[i]=max(dp[i-1 ...
随机推荐
- RS323串口连接仪器,接收仪器信息
SerialPort sp1 = new SerialPort(); getBloodPressur(); public void getBloodPressur() { try { string[] ...
- c++精度
- 在Docker中部署Confluence和jira-software
-------谢谢您的参考,如有疑问,欢迎交流 version: centos==7.2 jdk==1.8 confluence==6.15.4 jira-software==8.2.1 docker ...
- Java第六节课总结
动手动脑: 多层的异常捕获-1:ArrayIndexOutOfBoundsException/内层try-catch发生ArithmeticException多层的异常捕获-2:ArrayIndexO ...
- 《操作系统真象还原》MBR
以下是读本书第三章的收获. 如何知道一个源程序的各符号(指令和变量)地址?简单来说,地址就是该符号偏移文件开头的距离,符号的地址是按顺序编排的,所以两个相邻的符号,其地址也是相邻的.对于指令来说,指令 ...
- PUT方法写shell
前言: PUT是http的一个请求方法 PUT的前提,是了解HTTP协议.下面给出HTTP - PUT的一个模板: PUT /test.txt HTTP/1.1 Accept: */* Accept- ...
- Project Euler 133: Repunit nonfactors
题意 英文 做法 结论1:\(R(a)|R(am)(a,m\ge 1)\) \[\frac{R(am)}{R(a)}=\frac{\frac{10^{am}-1}{9}}{R(a)}=\frac{\f ...
- PHPMailer发送邮件遇坑小记
一:phpmailer发送邮件成功了 数据库发送状态也更改 但是用户就是没收到邮件. 出现原因:发送邮件太多 导致邮箱服务器被腾讯封了 发送的邮件统统进入了邮件服务器的草稿箱里. 解决方案: 重新修改 ...
- WebMethods开发入门
webMethods Integration Platform 由用于设计.执行和管理集成解决方案的 3 类组件构成. 设计时组件:这些组件提供了开发和测试集成解决方案的工具. 1.webMetho ...
- 合理使用Android提供的Annotation来提高代码的质量
概述 Java语言提供了Annotation的机制,让描述性的元数据能够和代码共存.通常我们可以利用Annotation,来做一些标志性的说明.然而Annotation必须和相应的解析工具一起才能工作 ...