NOIP2017提高组 模拟赛16(总结)
来源:互联网 发布:360解压软件下载 编辑:程序博客网 时间:2024/06/05 02:49
NOIP2017提高组 模拟赛16(总结)
第一题 比赛 (原题 noip2011 瑞士轮)
【题目描述】
【解题思路】
每一次比赛过后,赢的N名选手是有序的,输的N名选手也是有序的(赢的+1,赢的那N个都+1,对位置不会有影响。输的也是一样)。直接用O(N)的时间归并即可。
时间复杂度:O(N logN+RN)
【代码】
#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;const int N=200100;int n,t,ned;int D[N],q1[N],q2[N],p1,p2;struct data { int g,p,id; } d[N];bool cmp(int A,int B) { return (d[A].g>d[B].g || (d[A].g==d[B].g && A<B)); }int main(){ freopen("2241.in","r",stdin); freopen("2241.out","w",stdout); scanf("%d%d%d",&n,&t,&ned); n<<=1; for(int i=1;i<=n;i++) scanf("%d",&d[i].g); for(int i=1;i<=n;i++) scanf("%d",&d[i].p),D[i]=i; sort(D+1,D+1+n,cmp); while(t--) { p1=0; p2=0; for(int i=1;i<=n;i+=2) if(d[D[i]].p>d[D[i+1]].p) { d[D[i]].g++; q1[++p1]=D[i]; q2[++p2]=D[i+1]; } else { d[D[i+1]].g++; q1[++p1]=D[i+1]; q2[++p2]=D[i]; } p1=p2=1; for(int i=1;i<=n;i++) { if(p1<=(n>>1)) { if(d[q1[p1]].g>d[q2[p2]].g || (d[q1[p1]].g==d[q2[p2]].g && q1[p1]<q2[p2])) D[i]=q1[p1++]; else D[i]=q2[p2++]; } else D[i]=q2[p2++]; } } printf("%d\n",D[ned]); return 0;}
第二题 奶牛跑步
【题目描述】
【解题思路】
比赛持续了T=C*L/speed_max
奶牛i超过奶牛j的次数Pij=T*(speed_i-speed_j)/C=L/speed_max*(speed_i-speed_j),Pij要向下取整。
由于L/speed_max是小数,不好搞。
可以分开商和余数来做,先忽略掉余数(只考虑整数部分)
例如3.2-1.5就变成3-1=2。
那么这样是会算多的,因为0.2-0.5<0,必须答案-1。
用树状数组存余数就可以解决这一问题。
speed_max≤1000000,余数是存的下的。
(速度从小到大排序)
【代码】
#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;const int N=100100;int n,len,sp[N];ll T[1001000],ans,last,m,now;void add(int x) { for(int i=x;i<=sp[n];i+=(i&-i)) T[i]++; }ll query(int x){ ll yu=0ll; for(int i=x;i;i-=(i&-i)) yu+=T[i]; return yu;}bool cmp(int A,int B) { return (A<B); }int main(){ freopen("2242.in","r",stdin); freopen("2242.out","w",stdout); scanf("%d%lld%d",&n,&m,&len); for(int i=1;i<=n;i++) scanf("%d",&sp[i]); sort(sp+1,sp+1+n,cmp); last=0ll; ans=0ll; for(int i=1;i<=n;i++) { ll q=m*sp[i]/sp[n]; ll p=m*sp[i]%sp[n]; last+=q; now=q*i-last; add(p+1); now-=(i-query(p+1)); ans+=now; } printf("%lld\n",ans); return 0;}
第三题 T-shirt (cf183d)
【题目描述】
【解题思路】
50%
假设至少x人实际衬衫是k的概率是poss[k][x]
假设第1到第y个人中至少x人实际衬衫是k的概率是f[k][y][x]
f[k][y][x]=f[k][y-1][x-1] * pyk + f[k][y-1][x] * (1-pyk)
Poss[k][x] = f[k][n][x]
如果买x件衬衫,期望匹配数是sigma poss[k]i
可以发现,k一定时,poss[k]单调减小。而假设原来有x件k号衬衫,现在多买一件k号衬衫,那么第x+1件k号衬衫对答案的贡献是poss[k][x+1]
可以发现,答案是poss数组中,最大的n个数的和
时间复杂度O(N*N*M)
100%
利用单调性优化:如果poss[k][x]还未被选取,则必然不会选取poss[k][x+1].因此我们可以在选取了poss[k][x]后再计算poss[k][x+1]的值。
时间复杂度O(N*N+N*M)
【代码】
#include<cstdio>#include<algorithm>#define imax(a,b) (((a-b)>eps)?(a):(b))using namespace std;typedef long long ll;const double eps=1e-6;const int N=3010;const int M=310;int n,m,g[M];double fn[2][M][N],p[N][M],poss[M][2],ans;void letplay(int cl){ int yu=g[cl]&1^1; poss[cl][yu]=0.0; for(int i=1;i<=n;i++) fn[yu][cl][i]=fn[yu^1][cl][i-1]*p[i][cl]+fn[yu][cl][i-1]*(1.0-p[i][cl]); for(int i=0;i<=n;i++) fn[yu^1][cl][i]=0.0; poss[cl][yu]=fn[yu][cl][n]; g[cl]^=1;}int main(){ freopen("2243.in","r",stdin); freopen("2243.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { int a; scanf("%d",&a); p[i][j]=1.0*a/1000; } for(int i=1;i<=m;i++) { g[i]=0; for(int j=0;j<=n;j++) fn[0][i][j]=1.0; letplay(i); } poss[0][0]=0.0; g[0]=0; ans=0.0; for(int i=1;i<=n;i++) { int mx=0; for(int j=1;j<=m;j++) if(poss[j][g[j]&1]>poss[mx][g[mx]&1]) mx=j; ans+=poss[mx][g[mx]&1]; letplay(mx); } printf("%.8lf\n",ans); return 0;}
- NOIP2017提高组 模拟赛16(总结)
- NOIP2017提高组模拟赛4 (总结)
- NOIP2017提高组模拟赛5 (总结)
- NOIP2017提高组模拟赛 7(总结)
- NOIP2017提高组模拟赛 8(总结)
- NOIP2017提高组模拟赛 9 (总结)
- NOIP2017提高组模拟赛 10 (总结)
- NOIP2017提高组 模拟赛13(总结)
- NOIP2017提高组 模拟赛15(总结)
- NOIP2017提高组 模拟赛17(总结)
- NOIP2017提高组 模拟赛18(总结)
- NOIP2017提高组 模拟赛19(总结)
- NOIP2017提高组 模拟赛20(总结)
- NOIP2017提高组 模拟赛21(总结)
- NOIP2017提高组 模拟赛23(总结)
- NOIP2017提高组 模拟赛24(总结)
- NOIP2017提高组 模拟赛 26(总结)
- NOIP2017提高组 模拟赛 27(总结)
- java构造器
- 2017 ACM-ICPC 亚洲区(青岛赛区)网络赛总结
- 0918复习
- include指令和动作的区别
- 篇二:二叉树的一生
- NOIP2017提高组 模拟赛16(总结)
- Maven的Helloworld
- 凯儿得乐企业化系统平台开发
- 相反数
- 通知栏(Notification)的基本使用
- 使用python实现二分查找
- day11-Tomcat与Servlet入门
- new和newInstance() Constructor.newInstance()区别
- 展讯7731C_M Android6.0 充电指示灯实现