入门赛5
来源:互联网 发布:c语言开发环境 编辑:程序博客网 时间:2024/06/05 16:35
- 前言
- T1 Curriculum Vitae
- 题面
- 题意
- 思路
- 代码
- 小结
- T2 Math Show
- 题面
- 题意
- 思路
- 代码
- 小结
- T3 Four Segments
- 题面
- 题意
- 思路
- 代码n2
- 核心代码n3
- 小结
- T4 Monitor
- 题面
- 题意
- 思路
- 代码
- 小结
- T5 Chemistry in Berland
- 题面
- 题意
- 思路
- 代码AC
- 代码 树
- 小结
- T6 Random Query
- 题面
- 题意
- 思路
- 代码
- 小结
- 总结
前言
完全挂的一场比赛,差点就爆零了.
本赛涉及题目:
A: [Curriculum Vitae]B: [Math Show]
C: [Four Segments]
D: [Monitor]
E: [Chemistry in Berland]
F: [Random Query]
T1 Curriculum Vitae
题面
原题地址: [A]
题意
有n个数,不能改变数的顺序,问最少删除几个数使这个数串没有0在1的右边,输出这个数串的最大可能长度.
思路
我有两种思路,虽然有一种一直WA…(然而我看着没区别)
AC思路:
求出每个点左边0的个数和右边1的个数,求这两数和的最大值,再加上1就是答案(1是所枚的点)
代码
#include<bits/stdc++.h>using namespace std;int a[105],i,j,n,ans=1,ans_;int main(){ for(scanf("%d",&n),i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<n;i++) { ans_=0; for(j=0;j<=i;j++) if(a[j]==0) ans_++; for(j=i;j<n;j++) if(a[j]==1) ans_++; ans=max(ans,ans_); } printf("%d",ans); return 0;}
小结
为什么我的第一个思路不行!!!(还是不要贴出来吧…)
T2 Math Show
题面
原题地址: [B]
题意
有n个任务,每个任务都有k个子任务,且每个任务的子任务是一样的,每个子任务完成后都获得一个点数,一个大任务完成额外获得一个点数,求在M时间里最多获得的点数.
思路
由于数据范围比较小,可以爆枚完成大任务的个数,然后求点数的最大值,具体见代码.
代码
#include<bits/stdc++.h>using namespace std;#define N 50long long n,k,M,ans,tot,now,ans_,d,i,j,e;int t[N+5];int main(){ for(scanf("%d%d%d",&n,&k,&M),i=0;i<k;i++) scanf("%d",&t[i]),tot+=t[i];//求完成一个大任务所需的时间; sort(t,t+k);//初始化; for(e=0;e<=n;e++) { now=tot*e;//完成e个大任务所需的时间; if(now>M) break;//此时时间超限,以后也必定超限,故退出; ans_ = (k+1)*e;//此时所获得的点数(大任务); for(i=0;i<k;i++) { for(j=e+1;j<=n;j++)//将余下的时间分配到小任务里; { now+=t[i]; ans_++; if(now>M) { ans_--;//最后使时间超限的点数去掉; i=k+1; break; } } } ans=max(ans,ans_);//求最大值; } printf("%d",ans); return 0;}
小结
扫一眼题面,我还以为这题不可做,然后就没写,没想到怎么水.
T3 Four Segments
题面
原题地址: [C]
题意
定义sum(x,y)为区间[a[x],a[y])的数字和,求三个点使sum(0,d1)-sum(d1,d2)+sum(d2,d3)-sum(d3,n) max. a数组是从零开始存数.
思路
求出前缀和的变式(a[i]存sum(0,i)),通过计算我们发现其实这个变式就是前缀和往后移以为,开头补0,这样可以用
for(i=1;i<=n;i++) scanf("%d",&a[i]),a[i]+=a[i-1]
来算前缀和,此时的sum(x,y)=a[y]-a[x];
原式=2*(a[d3]-a[d2]+a[d1])-a[n];
要使原式最小,只要使a[d3]-a[d2]+a[d1]最小,此时可以爆枚,但因为数据范围,n^3会TLE,于是又要加一步优化:
枚举d2的值,d3就是[a[d2],a[n]]的最大值的下标,d1就是[a[0],a[d2]]的最大值的下标,此时时间复杂度O(n^2).
代码#n^2
#include<bits/stdc++.h>#define inf 0x7f7f7f7fusing namespace std;long long ans=-inf,n,i,j,k,t[5007],d1,d2,d3,d1_,d2_,d3_,x,ans1,ans2,ans3;int main(){ for(scanf("%lld",&n),i=1;i<=n;i++) { scanf("%lld",&x); t[i]=x+t[i-1]; } for(d2_=0;d2_<=n;d2_++) { d2=d2_;d1=d3=d2; for(d1_=0;d1_<=d2_;d1_++) if(t[d1_]>=t[d1]) d1=d1_; for(d3_=d2_;d3_<=n;d3_++) if(t[d3_]>=t[d3]) d3=d3_; if(t[d1]+t[d3]-t[d2]>=ans) { ans=t[d1]+t[d3]-t[d2]; ans1=d1; ans2=d2; ans3=d3; } } printf("%lld %lld %lld",ans1,ans2,ans3); return 0;}
核心代码#n^3
for(d1_=0;d1_<=n;d1_++){ for(d2_=d1_;d2_<=n;d2_++) { for(d3_=d2_;d3_<=n;d3_++) { if(t[d1_]+t[d3_]-t[d2_]>=ans) { ans=t[d1_]+t[d3_]-t[d2_]; d1=d1_;d2=d2_;d3=d3_; } } }}
小结
重点是n^2的优化难想,我考完了才想到这种优化.
T4 Monitor
题面
原题地址: [D]
题意
有一个n*m的方阵,有些点会在某个时间坏掉,当坏掉的点组成一个k*k的方阵时,这个大方阵就变坏了,输出最小方阵变坏的时间,如果不可能变坏,输出-1。
思路
先将时间排序一下,每次更新ans,并将一个点置成坏,然后算一下有没有k*k的坏点。
如果爆枚k*k的方阵,但时间复杂度为q*n*m*k*k,直接爆
此时可以优化成每个点存其左上角k*k个点中坏掉的点的个数,当这个点到达k*k时,这个方阵就坏掉了。
此时每个点坏掉之后,向左下扩展一个k*k的方阵。
但这样时间复杂度为n^3*m,还是会TLE。
所以用另一种方式(抄的)(原理不会讲):
代码
#include<cstdio>#include<algorithm>using namespace std;struct Point{ int x,y,t; bool operator<(const Point& b) const { return t<b.t; }}p[255000];int b[510][510];bool c[510][510];int n,m,k,q;bool judge(int x,int y){ int i,ans=0; for(i=x;i<=n;i++) { if(b[i][y]<k) break; ans++; if(ans>=k) break; } for(i=x-1;i>=1;i--) { if(b[i][y]<k) break; ans++; if(ans>=k) break; } if(ans>=k) return true; else return false;}int main(){ int i,j; bool boo; scanf("%d%d%d%d",&n,&m,&k,&q); for(i=1;i<=q;i++) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].t); sort(p+1,p+q+1); for(i=1;i<=q;i++) { int& x=p[i].x; int& y=p[i].y; c[x][y]=true; for(j=y;j>=1;j--) { if(!c[x][j]) break; b[x][j]=b[x][j+1]+1; if(b[x][j]>=k) { boo=judge(x,j); if(boo==true) { printf("%d",p[i].t); return 0; } } } } printf("-1"); return 0;}
小结
其实还可以打二分,只是代码太长,懒得打。
T5 Chemistry in Berland
题面
原题地址: [E]
题意
有n种化学药品,拥有b1~bn,需要a1~an,有n-1条化学方程,第i个xi,ki代表ki个xi药品可以换成i+1药品,但1个i+1药品只能换成1个xi药品。
(此处的xi,i+1都是药品编号,i从1开始计数)
思路
刚开始是想建一棵数,从每个叶子节点一路换到树顶,再判断树顶,然后在第6个点WA了,因为是第6个点,所以我以为我代码错了,调了半天没调出来,于是又换了一种思路。
题目中有个条件1 ≤ x(j + 1 )≤ j,表示第i种药品只能转化成1~i-1种药品,于是就可以从尾部开始扫,再判断头部,此时还是WA6,看来不是我代码错了,再看一下数据范围,发现连long long 都能爆,所以改成double,然后就完美了。
代码AC
#include<bits/stdc++.h>#define N 100000#define LL long longusing namespace std;pair<LL,LL> change[N+5];LL x,n,i;double need[N+5];int main(){ for(scanf("%lld",&n),i=1;i<=n;i++) scanf("%lf",&need[i]); for(i=1;i<=n;i++) scanf("%lld",&x),need[i]=x-need[i]; for(i=2;i<=n;i++) scanf("%lld%lld",&change[i].first,&change[i].second); for(i=n;i>1;need[i]=0,i--) need[change[i].first]+=need[i]>0?1LL*need[i]*change[i].second:need[i]; need[1]>0?printf("NO"):printf("YES"); return 0;}
代码 树
//一直卡23点,不知道为什么,求各位dalao看看;#include<bits/stdc++.h>#define N 100000#define LL long longusing namespace std;struct Line{ int v,k;}line[N+5];long long head[N+5],away[N+5]/*入度计算*/,e,n,i,j,x,k;double tree[N+5],r;void add(int u,int v,int k){ line[e].v=v; line[e].k=k; head[u]=e; e++; away[v]++;}int main(){ memset(head,-1,sizeof(head)); scanf("%lld",&n); for(i=1;i<=n;i++) scanf("%lf",&tree[i]); for(i=1;i<=n;i++) scanf("%lf",&r),tree[i]-=r; for(i=2;i<=n;i++) { scanf("%lld%lld",&x,&k); add(i,x,k);//叶子指向根; } for(i=1;i<=n;i++) { if(!away[i])//判断叶子节点; { x=i; while(x!=1)//往根走; { if(tree[x]>=0) tree[line[head[x]].v]+=tree[x]; else tree[line[head[x]].v]+=tree[x]*line[head[x]].k*1LL; x=line[head[x]].v; } } } tree[x]>=0?printf("YES"):printf("NO"); return 0;}
小结
为什么第六个点就爆long long 了,出题人也太坑了吧,我还以为我代码错了呢!!!
T6 Random Query
题面
原题地址: [F]
题意
不会讲。
思路
只用计算的贡献
代码
#include<bits/stdc++.h>const int N=1e6;using namespace std;int i,head[N+5];long long ans;int main(){ for(scanf("%d",&n),i=1;i<=n;i++) { scanf("%d",&x);ans+=(long long)(i-head[x])*(n-i+1)*2;head[x]=i; } ans-=n; printf("%.12lf",(double)ans/n/n); return 0;}
小结
代码抄的~~
总结
e~~~,想法都是有的,代码都是WA的。。。
- 入门赛5
- 入门赛2
- 入门赛3
- 入门赛4
- 入门赛6
- 入门赛7
- 入门赛8
- 入门赛9
- 入门赛10
- 入门赛11
- 入门赛12
- 5、Hibernate入门5
- ADO.NET入门(5)
- ADO.NET入门 5
- 入门学习(5)
- PHP入门学习5
- cegui 5 输入输出入门
- Python入门5
- __FILE__,realpath和dirname,
- redis命令大全(二)
- 数据库三范式简单记
- HDU 5037 题解
- python读写txt——实现qq记录格式优化
- 入门赛5
- SpringMVC接收数组
- NetBeans配置Xdebug 远程调试PHP
- 从零开始学Scala(一)——Scala环境搭建与第一行代码
- Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises) A,B,C
- bootstarp table 使用及常用参数说明
- Resharper快捷键与VS冲突
- 4种方法解决为 li列表 添加事件问题(for循环经典问题)
- linux搭建ss