Educational Codeforces Round 54
这套题不难,但是场上数据水,导致有很多叉点
A.
因为是让求删掉一个后字典序最小,那么当a[i]>a[i+1]的时候,删掉a[i]一定最优!这个题有个叉点,当扫完一遍如果没有满足条件的,就删去最后一个字符。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <set> 6 #include <map> 7 #include <vector> 8 #include <queue> 9 #include <cmath> 10 #include <cstdlib> 11 #include <stack> 12 13 using namespace std; 14 const double eps = 1e-6; 15 const int MOD=1e9+7; 16 typedef long long LL; 17 typedef unsigned long long ull; 18 const int INF=2147000000; 19 const LL inf = 1e18; 20 LL gcd(LL a,LL b){ 21 if(!b)return a; 22 return gcd(b,a%b); 23 } 24 LL lcm(LL a,LL b){ 25 return a/gcd(a,b)*b; 26 } 27 const int maxn=2e5+100; 28 char s[maxn]; 29 int n; 30 int main(){ 31 scanf("%d",&n); 32 scanf("%s",s); 33 int pos=-1; 34 for(int i=0;i<n-1;i++){ 35 if(s[i+1]<s[i]){ 36 pos=i; 37 break; 38 } 39 } 40 if(pos==-1) 41 pos=n-1; 42 for(int i=0;i<n;i++) 43 if(i!=pos) 44 printf("%c",s[i]); 45 return 0; 46 }
View Code
B.
当n是偶数的时候一定是每次都减2,也就是n/2.当n奇数的时候,就暴力减质数一直减到是偶数或者为0.注意要特判当前n是不是质数。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <set> 6 #include <map> 7 #include <vector> 8 #include <queue> 9 #include <cmath> 10 #include <cstdlib> 11 #include <stack> 12 13 using namespace std; 14 const double eps = 1e-6; 15 const int MOD=1e9+7; 16 typedef long long LL; 17 typedef unsigned long long ull; 18 const int INF=2147000000; 19 const LL inf = 1e18; 20 LL gcd(LL a,LL b){ 21 if(!b)return a; 22 return gcd(b,a%b); 23 } 24 LL lcm(LL a,LL b){ 25 return a/gcd(a,b)*b; 26 } 27 const int maxn=2e5+100; 28 29 int prime[maxn]; 30 int vis[maxn]; 31 int num; 32 int init(int n){ 33 int m = (int)sqrt(n); 34 vis[1]=1; 35 36 for(int i = 2;i<=m;i++){ 37 for(int j =i*i; j<=n;j+=i){ 38 vis[j]=1; 39 } 40 } 41 for(int i=2;i<=n;i++){ 42 if(!vis[i]){ 43 num++; 44 prime[num] = i; 45 } 46 } 47 return num; 48 } 49 bool judge(LL x){ 50 int m =(int)sqrt(x); 51 for(int i=2;i<=m+1;i++){ 52 if(x%i==0) 53 return false; 54 } 55 return true; 56 } 57 LL n; 58 int 59 main(){ 60 cin>>n; 61 LL ans=0; 62 init(2e5); 63 if(n%2==0){ 64 cout<<n/2<<endl; 65 return 0; 66 } 67 bool ok=1; 68 while(n%2){ 69 if(judge(n)){ 70 ans+=1; 71 ok=0; 72 break; 73 } 74 75 int flag=0; 76 for(int i=1;i<=num&&prime[i]<=n;i++){ 77 if(n%prime[i]==0){ 78 // printf("!!%d\n",prime[i]); 79 flag=prime[i]; 80 break; 81 } 82 } 83 //printf("%d\n",flag); 84 if(!flag)flag=n; 85 n-=flag; 86 ans++; 87 } 88 if(ok) 89 ans+=n/2; 90 cout<<ans<<endl; 91 return 0; 92 }
View Code
C.
这个题就是解一个一元二次方程,应该也可以三分来做。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <set> 6 #include <map> 7 #include <vector> 8 #include <queue> 9 #include <cmath> 10 #include <cstdlib> 11 #include <stack> 12 13 using namespace std; 14 const double eps = 1e-6; 15 const int MOD=1e9+7; 16 typedef long long LL; 17 typedef unsigned long long ull; 18 const int INF=2147000000; 19 const LL inf = 1e18; 20 LL gcd(LL a,LL b){ 21 if(!b)return a; 22 return gcd(b,a%b); 23 } 24 LL lcm(LL a,LL b){ 25 return a/gcd(a,b)*b; 26 } 27 int main(){ 28 int T; 29 scanf("%d",&T); 30 31 int d; 32 for(int kas=1;kas<=T;kas++){ 33 scanf("%d",&d); 34 double del = d*d - 4*d; 35 if(del<0){ 36 printf("N\n"); 37 }else if(del == 0){ 38 double ans=(double)d/2; 39 40 printf("Y %.9f %.9f\n",ans,(double)(d-ans)); 41 }else{ 42 double ans1 = (double)(d+sqrt(del))/2; 43 if(ans1<=d){ 44 printf("Y %.9f %.9f\n",ans1,(double)(d-ans1)); 45 }else{ 46 double ans1 = (double)(d-sqrt(del))/2; 47 if(ans1<0){ 48 printf("N\n"); 49 }else 50 printf("Y %.9f %.9f\n",ans1,(double)(d-ans1)); 51 } 52 } 53 } 54 return 0; 55 }
View Code
D.
最短路+贪心;我们先跑出最短路树来,如果k大于等于最短路树的边数,则树上的边全留下。否则的话就要删树上的边,删哪些呢?从最远(d[u]最大)的边开始删一定是最优的。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <set> 6 #include <map> 7 #include <vector> 8 #include <queue> 9 #include <cmath> 10 #include <cstdlib> 11 #include <stack> 12 13 using namespace std; 14 const double eps = 1e-6; 15 const int MOD=1e9+7; 16 typedef long long LL; 17 typedef unsigned long long ull; 18 const int INF=2147000000; 19 const LL inf = 1e18; 20 LL gcd(LL a,LL b){ 21 if(!b)return a; 22 return gcd(b,a%b); 23 } 24 LL lcm(LL a,LL b){ 25 return a/gcd(a,b)*b; 26 } 27 const int maxn=3e5+100; 28 int head[maxn],to[2*maxn],Next[2*maxn],w[2*maxn],id[2*maxn]; 29 struct Edge{ 30 int from,to,w,id; 31 }; 32 vector<Edge>edges; 33 int sz,n,m,k; 34 void init(){ 35 sz=0; 36 memset(head,-1,sizeof(head)); 37 } 38 void add_edge(int a,int b,int c,int d){ 39 ++sz; 40 to[sz]=b; 41 w[sz]=c; 42 id[sz]=d; 43 Next[sz]=head[a]; 44 head[a]=sz; 45 } 46 struct HeapNode{ 47 int u; 48 LL d; 49 int from; 50 bool operator <(const HeapNode& rhs)const{ 51 return d>rhs.d; 52 } 53 }; 54 int done[maxn],p[maxn]; 55 LL d[maxn]; 56 57 Edge edge[maxn]; 58 59 priority_queue<HeapNode>q; 60 void dij(){ 61 q.push((HeapNode){1,0,-1}); 62 for(int i=0;i<=n;i++) 63 d[i]=inf; 64 while(!q.empty()){ 65 HeapNode x= q.top();q.pop(); 66 if(done[x.u]) 67 continue; 68 done[x.u]=1; 69 d[x.u] = x.d; 70 p[x.u] = x.from; 71 //printf("%d\n",x.from); 72 for(int i=head[x.u];i!=-1;i=Next[i]){ 73 int v = to[i]; 74 if(d[v]>d[x.u]+w[i]){ 75 q.push((HeapNode){v,d[x.u]+w[i],id[i]}); 76 } 77 } 78 } 79 } 80 81 struct Node{ 82 int u; 83 LL d; 84 int from; 85 bool operator <(const Node &rhs)const{ 86 return d<rhs.d; 87 } 88 }; 89 int vis[maxn]; 90 91 priority_queue<Node>Q; 92 93 int main(){ 94 scanf("%d%d%d",&n,&m,&k); 95 96 init(); 97 for(int i=1;i<=m;i++){ 98 int a,b,c; 99 scanf("%d%d%d",&a,&b,&c); 100 add_edge(a,b,c,i); 101 add_edge(b,a,c,i); 102 edge[i]=(Edge){a,b,c,i}; 103 } 104 dij(); 105 for(int i=1;i<=n;i++){ 106 //printf("@%d\n",p[i]); 107 if(p[i]!=-1&& !vis[p[i]]){ 108 edges.push_back(edge[p[i]]); 109 vis[p[i]]=1; 110 Q.push((Node){i,d[i],p[i]}); 111 // printf("!!!%d %d %d %d\n",edge[p[i]].from,edge[p[i]].to,edge[p[i]].w,p[i]); 112 } 113 } 114 if(edges.size()<=k){ 115 printf("%d\n",edges.size()); 116 for(int i=0;i<edges.size();i++){ 117 printf("%d ",edges[i].id); 118 } 119 }else{ 120 int num = edges.size(); 121 while(num>k&&!Q.empty()){ 122 Q.pop(); 123 num--; 124 } 125 printf("%d\n",k); 126 while(!Q.empty()){ 127 printf("%d ",Q.top().from); 128 Q.pop(); 129 } 130 } 131 return 0; 132 }
View Code
E.
树状数组或者线段树维护一下。因为每个点的值只可能是来自于它的祖先结点,所以跑dfs的时候,进入这个点的时候更新树状数组,退栈的时候还原树状数组
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <vector> 6 7 using namespace std; 8 const int maxn=3e5+100; 9 typedef long long LL; 10 int head[maxn],to[2*maxn],Next[2*maxn]; 11 int n,sz,m; 12 void add_edge(int a,int b){ 13 sz++; 14 to[sz]=b;Next[sz]=head[a];head[a]=sz; 15 } 16 int lowbit(int x){ 17 return x&(-x); 18 } 19 LL sumv[maxn]; 20 void update(int x,int v){ 21 while(x<=n){ 22 sumv[x]+=v; 23 x+=lowbit(x); 24 } 25 } 26 LL query(int x){ 27 LL res=0; 28 while(x){ 29 res+=sumv[x]; 30 x-=lowbit(x); 31 } 32 return res; 33 } 34 struct Node{ 35 int d,x; 36 }; 37 vector<Node>V[maxn]; 38 int fa[maxn],dep[maxn]; 39 LL ans[maxn]; 40 41 void dfs(int u,int Fa,int depth){ 42 fa[u]=Fa; 43 dep[u]=depth; 44 for(int i=0;i<V[u].size();i++){ 45 Node N = V[u][i]; 46 update(min(N.d+depth,n),N.x); 47 } 48 ans[u] = query(n)-query(depth-1); 49 for(int i=head[u];i!=-1;i=Next[i]){ 50 int v=to[i]; 51 if(v==Fa)continue; 52 dfs(v,u,depth+1); 53 } 54 for(int i=0;i<V[u].size();i++){ 55 Node N = V[u][i]; 56 update(min(N.d+depth,n),-N.x); 57 } 58 } 59 60 int main(){ 61 scanf("%d",&n); 62 memset(head,-1,sizeof(head)); 63 for(int i=1;i<n;i++){ 64 int a,b; 65 scanf("%d%d",&a,&b); 66 add_edge(a,b); 67 add_edge(b,a); 68 } 69 scanf("%d",&m); 70 for(int i=1;i<=m;i++){ 71 int v,d,x; 72 scanf("%d%d%d",&v,&d,&x); 73 V[v].push_back((Node){d,x}); 74 } 75 dfs(1,-1,1); 76 for(int i=1;i<=n;i++){ 77 printf("%I64d ",ans[i]); 78 } 79 return 0; 80 }
View Code
F.
贪心+分类讨论。
每一页多的为Max,少的为Min。那么一定是用少的将多的分隔开。所以如果大小关系不同则不会产生影响。否则的话,这一页我们要它最左边多出来的那块尽量长。lef=k-lastR;那么Max=Max-lef,Min=Min-1;然后我们分类讨论:
1.ceil(Max/k)-1>Min 则return false;
2.ceil(Max/k)<=Min
则说明右边不会剩下。则lastR=0。
3.ceil(Max/k)==Min-1的话,恰好被分割开,右边会有剩余,但是剩余的长度<=k,属于合法。
lastR= Max%k ==0?k:Max%k
这个也有叉点,要主要Min==Max的情况
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 #include <cstdlib> 7 8 using namespace std; 9 const int maxn = 3e5 + 100; 10 int n, k; 11 int x[maxn][2];//0 x,1 y 12 int state,laststate,lastR; 13 int main(){ 14 scanf("%d%d", &n, &k); 15 for(int i = 1; i <= n; i++){ 16 scanf("%d", &x[i][0]); 17 } 18 for(int i = 1; i <= n; i++){ 19 scanf("%d", &x[i][1]); 20 } 21 bool flag = 1; 22 for(int i = 1; i <= n; i++){ //x >= y state = 1;else state = 0; 23 int Min = min(x[i][0], x[i][1]); 24 int Max = max(x[i][0], x[i][1]); 25 // printf("%d %d\n",Min,Max); 26 if(x[i][0] > x[i][1]) 27 state = 1; 28 else if(x[i][0] < x[i][1]) 29 state = 0; 30 else state = -1; 31 if(state == laststate||laststate == -1||state == -1){ 32 int lef = k - lastR; 33 Max = Max - lef; 34 Min = Min - 1; 35 } 36 //printf("%d %d\n",(int)ceil((double)Max/k),Min); 37 38 if((int)ceil((double)Max/k)-1 > Min){ 39 flag = 0; 40 break; 41 }else if((int)ceil((double)Max/k) <= Min){ 42 lastR = 0; 43 }else{ 44 lastR = Max%k == 0?k:Max%k; 45 } 46 laststate = state; 47 } 48 if(!flag){ 49 printf("NO\n"); 50 }else{ 51 printf("YES\n"); 52 } 53 return 0; 54 }
View Code
G.
好像是打反转标记的线段树,留坑
转载于:https://www.cnblogs.com/LQLlulu/p/9955849.html
Educational Codeforces Round 54相关推荐
- Educational Codeforces Round 54 (Rated for Div.2)
Educational Codeforces Round 54 (Rated for Div.2) D. Edge Deletion 题意:一张n个点的无向图,保留其中k条边,使得有尽可能多的点与1的 ...
- Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)
题目大意:给定你一个包含n个点m条边的无向图,现在最多在图中保留k条边,问怎么删除多的边,使得图中良好的节点数最多,求出保留在图中的边的数量和编号. 良好的节点定义为:删除某条边后该点到点1的最短距离 ...
- Educational Codeforces Round 54 (Rated for Div. 2): D. Edge Deletion(最短路树)
题意: 给你n个点m条边的无向图,其中1号节点是市中心,你现在最多只能保留k条边,并要求所有点到市中心的最短路尽量不变(也就是说设点i到点1的最短路为di,那么删边之后,要保证尽可能多的点,它到1的最 ...
- Educational Codeforces Round 54 (Rated for Div. 2): E. Vasya and a Tree(DFS+差分)
题意: 给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值 ...
- cf Educational Codeforces Round 54 C. Meme Problem
原题: C. Meme Problem time limit per test1 second memory limit per test256 megabytes inputstandard inp ...
- Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)
Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...
- Educational Codeforces Round 24 E. Card Game Again(双指针)
题目链接:Educational Codeforces Round 24 E. Card Game Again 题意: 给你n个数和一个数k. 现在每次可以拿掉前x个数,后y个数,剩下的数的乘积要能被 ...
- [Educational Codeforces Round 16]A. King Moves
[Educational Codeforces Round 16]A. King Moves 试题描述 The only king stands on the standard chess board ...
- Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...
最新文章
- [C#] 查标准正态分布表
- InnoDB: Error: log file .\ib_logfile0 is of different size 0 10485760 bytes
- 百度网盘文件分享演示,如何查看已经分享的文件
- AtCoder AGC002F Leftmost Ball (DP、组合计数)
- 安卓Socket处理
- [luogu4027] [NOI2007]货币兑换
- iOS开发 蓝牙技术4.0详解
- [渝粤教育] 广东-国家-开放大学 互联网营销概论
- 【LeetCode】查找只出现一次的数字算法
- 将node.js程序作为服务,并在windows下开机自动启动(使用forever)
- android okhttputils传数组,okhttp传递数组参数
- 与大家分享一些计算机方面的电子书籍
- 数据分析师面试简历怎么做?
- html5橡皮擦,HTML5 Canvas笔记——实现橡皮擦功能,包括矩形擦和圆形擦。
- 最简单易懂的git介绍
- 在mysql中创建用户并授权
- 判断图片是否为现场照片(Live Photo亦即内含Exif信息)
- HIVE常用参数配置
- springmvc生成二维码
- ECC有关DER文件的解析(Java)
热门文章
- poj2965-poj2965-The Pilots Brothers' refrigerator
- 视觉SLAM中PNP求解
- java 设计一个geometricobject类,geometricobject类
- usaco contact
- java常用的集合对象_java常用实体类、集合类
- 语言解决猜神童年龄的问题_一个程序设计题目猜年龄(不限程序语言)
- oracle无创建directory权限,【DIRECTORY】普通用户创建Oracle DIRECTORY数据库对象的权限需求及探索...
- python编的俄罗斯方块游戏下载_python写的俄罗斯方块游戏
- mysql 数字区间_币投君0904丨数字货币暴跌原因何在
- Linux上运行一个c程序