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;
}
就是这样
评论 (0)