ZHOJ2015-08-08 真·NOIP模拟赛
100+15(这是什么回事)+10,暴力写写真心没救了
T1:lyd的旅行
【题目描述】
众所周知,lyd是一个人赢。他有很多很多的妹子
某天,他带着他的众多妹子进行了一次旅(dou)行(feng),由于lyd的车上妹子太多超重了,所以车速每秒最多只能改变d个单位,lyd在出发和回家前都看了速度表,记下了出发的初速度v1和回家的末速度v2,以及行驶时间t,但是由于中途lyd和妹子(bi---)了,所以他并不知道中途行驶了多长路程。
现在lyd想知道他最多行驶了多长路程。
【输入数据】
第一行两个整数v1,v2
第二行两个整数t和d
意义如题所示
【输出数据】
一行一个整数表示答案
【样例输入1】
5 6
4 2
【样例输出1】
26
【样例输入2】
10 10
10 0
【样例输出2】
100
【样例解释】
样例1:每个单位的时间分别是5,7,8,6,答案=5+7+8+6=26
样例2:反正速度不能变,就一直开下去好了
【数据规模与约定】
对于100%的数据
1<=v1,v2<=100
2<=t<=100
0<=d<=10
【提醒】
谁告诉你单位时间和单位速度可以分割了!
【后记】
Lyd大爷使用了lydtree回到了过去重新进行了一次旅行,于是他就不需要泥了~
(窝只是单纯地上传一下题目而已,不过作为一个妹子,看这个题面总觉得怪怪的)
暴力+暴力+暴力+暴力+……
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; int v1,v2,t,a; int va[200],vb[200]; int ans; int main() { scanf("%d%d",&v1,&v2); scanf("%d%d",&t,&a); va[1]=v1; vb[1]=v2; for (int i=2;i<=t;++i) { va[i]=va[i-1]+a; vb[i]=vb[i-1]+a; } ans=0; for (int i=1;i<=t;++i) { ans+=min(va[i],vb[t-i+1]); } printf("%d\n",ans); return 0; }
T2:lj的锁
【题目描述】
Lj花很大力气设计了一个锁,有一天,lj用这个锁把lbn锁在了一个小房间里,准备把lbn啊掉,现在lbn要逃出这个房间,他需要解开这个锁。
在平面上有n个钉子,第i个钉子的位置是(x[i],0),你需要回答m个问题,每个问题都是如下格式的:如果在第a[i]个钉子上挂一条长为l[i],末端有一个重锤的轻绳,并让它沿逆时针方向做圆周运动,显然由于大量钉子的存在,绳子会绕在一些钉子上并最终围绕其中一个钉子做圆周运动,求最后绳子做圆周运动的圆心是哪颗钉子。
然而lj还有2s就要抓到lbn了,lbn为了逃命不得不求助于你,让你帮他解决那些数不清的询问。
【输入数据】
第一行两个整数n,m(1<=n,m<=2*10^5),代表钉子的个数和询问的个数
第二行n个整数x[1],x[2],…,x[n](-10^9<=x[i]<=10^9),代表钉子的横坐标,保证坐标各不相同
接下来m行,每行两个整数a[i],l[i](1<=a[i]<=n,1<=l[i]<=10^9),代表一个询问中绳子最初挂在的钉子编号以及绳子的长度
【输出数据】
m行,每行一个数,表示每个询问中绳子最后会绕哪颗钉子做圆周运动
【样例输入】
4 4
1 5 7 15
1 4
2 15
3 16
1 28
【样例输出】
2
4
3
1
【样例解释】
注意在最后一个询问中我们认为绳子绕1号钉子做半径为0的圆周运动。
【数据规模与约定】
对于100%的数据,范围详见输入格式
对于30%的数据,数据是随机的
对于10%的数据,n,m<=1000
【后记】
由于测了太多组数据,导致总时间>2s,lbn还是被啊掉了
(就是觉得题目真好玩)
一开始的15分自己都不知道是怎么写的,肯定是二分写跪了
然后发现其实就是在二分的基础上优化一下。。。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define NN 200020 using namespace std; struct REC { int sum,p; REC (int _=0):sum(_),p(0){} }; REC a[NN]; int ne,la,t,n,m,len,x; int E[NN]; bool cmp(const REC xx,const REC yy) { return xx.sum<yy.sum; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) scanf("%d",&a[i].sum),a[i].p=i; sort(a+1,a+n+1,cmp); for (int i=1;i<=n;++i) E[a[i].p]=i; while (m--) { scanf("%d%d",&x,&len); int k=1; la=E[x]; while (len>0) { if (k&1) { ne=upper_bound(a+1,a+1+n,REC(a[la].sum+len),cmp)-a-1; if (k>1&&ne==la) break; if (k==1) { k++,len-=abs(a[la].sum-a[ne].sum),la=ne; } else { int tmp=len/abs(a[la].sum-a[ne].sum); k+=tmp,len%=abs(a[la].sum-a[ne].sum); if (tmp&1) la=ne; } } else { ne=lower_bound(a+1,a+1+n,REC(a[la].sum-len),cmp)-a; if (ne==la) break; int tmp=len/abs(a[la].sum-a[ne].sum); k+=tmp,len%=abs(a[la].sum-a[ne].sum); if (tmp&1) la=ne; } } printf("%d\n", a[la].p); } return 0; }
一开始总是死循环,发现+/-号写错了,然后upper_bound/lower_bound写反了,人兔生真没希望。。
T3:vfk的地雷
(前面有好多图,于是就偷懒了)
为了方便起见,我们可以认为每一句言会有一定概率触发地雷。
其判定机制如下:
在每一句话中,vfk将从第一个地雷开始,按照顺序依次考虑每个地雷。
在一句话中,对于依次考虑的每一个地雷:
1如果这个地雷在之前中已经被触发过,则
1.1 如果这个地雷不是最后一个,则跳过之(考虑下一个地雷);
否则(是最后一张),结束这一句话,考虑下一句。
2否则(这个地雷没有被触发),设这个地雷为第i个
2.1将其以 pi的概率触发。
2.2如果地雷被触发,则对泉岭精神造成di个单位时间的禁言,并结束这一句话。
2.3(如果没被触发)如果这个地雷已经是最后一个(即i等于n),则结束这一句话;否则,考虑下一个地雷。
求期望禁言时间
【输入数据】
第一行包含一个整数 T,代表测试数据组数。
接下来一共 T 组数据。
每组数据的第一行包含两个用空格分开的整数n和r,分别代表地雷的个数和水群个数。
接下来n行,每行包含一个实数和一个整数,由空格隔开,描述一个地雷。
第i行的两个数为pi和di,意义如上所示
保证 pi最多包含 4位小数,且为一个合法的概率。
【输出数据】
对于每组数据,输出一行,包含一个实数,为答案
对于每一行输出,只有当你的输出和标准答案的误差不超过10^-8时,你的输出才会被判为正确。
建议输出10 位小数。
【样例输入】
1
3 2
0.8564 774
0.6018 418
0.9458 57
【样例输出】
1033.8031096438
【数据规模与约定】
对于所有测试数据,1≤T≤444,1≤n≤220,0≤r≤132,0<pi<1,0≤di≤1000。
请注意可能存在的实数精度问题,并采取适当措施。
【后记】
陈老师和杜老师踩到了地雷,被禁言了,然后一怒之下退群了QAQ
(好难)
不会做,就写了发暴力,10分
标算DP,于是作为一个DP弱渣,先搁在一边,于是希望拖延症别让我拖太久QAQ
#include<cstdio> #include<cstring> using namespace std; double ans; double p[300]; int d[300],b[300]; int r,n,T; #define gch getchar #define mp make_paira char C_get; void read(double &x) { for(x=0,C_get=gch();(C_get<'0'||C_get>'9')&&C_get!='-'&&C_get!='+';C_get=gch()); if(C_get=='-') { for(C_get=gch();C_get>='0'&&C_get<='9';C_get=gch())x=x*10-C_get+'0'; if(C_get=='.') { double n=1; for(C_get=gch();C_get>='0'&&C_get<='9';C_get=gch())n/=10,x=x-(C_get+'0')*n; } } else { if(C_get=='+')C_get=gch(); for(;C_get>='0'&&C_get<='9';C_get=gch())x=x*10+C_get-'0'; if(C_get=='.') { double n=1; for(C_get=gch();C_get>='0'&&C_get<='9';C_get=gch())n/=10,x=x+(C_get-'0')*n; } } } void dfs(int xx,double pp) { if (xx==r+1) return; double tmp=1; for (int i=1;i<=n;i++) if (!b[i]) { double tmpp=pp*tmp*p[i]; b[i]=1,ans+=tmpp*d[i]; dfs(xx+1,tmpp); tmp*=(1-p[i]),b[i]=0; } dfs(xx+1,tmp); } void read(int &x) { for(x=0,C_get=gch();(C_get<'0'||C_get>'9')&&C_get!='-'&&C_get!='+';C_get=gch()); if(C_get=='-') { for(C_get=gch();C_get>='0'&&C_get<='9';C_get=gch())x=x*10-C_get+'0'; } else { if(C_get=='+')C_get=gch(); for(;C_get>='0'&&C_get<='9';C_get=gch())x=x*10+C_get-'0'; } } int main() { scanf("%d",&T); while (T--) { ans=0; scanf("%d%d",&n,&r); for (int i=1;i<=n;i++) read(p[i]),read(d[i]); dfs(1,1); printf("%.10lf\n",ans); } return 0; }
就是这样