B 牛牛战队的比赛地
添加链接描述
链接:https://ac.nowcoder.com/acm/contest/3006/B
来源:牛客网
由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标(x,y)(x,y)。
这周末,牛牛队又要出去比赛了,各个比赛的赛点都在xx轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。
这个问题对于牛牛战队太简单了,它就交给了你,你来帮他算一下~
输入描述:
输入数据第一行包含一个整数N(1 \leq N \leq 100\,000)N(1≤N≤100000),表示牛牛战队训练基地的数量。
接下来NN行,每行包括22个整数x,y(-10\,000 \leq x,y \leq 10\,000)x,y(−10000≤x,y≤10000),表示每一个训练基地的坐标。
输出描述:
输出一个小数,表示选择的比赛地距离各训练基地最大距离的最小值。
如果你的答案是aa,标准答案是bb,当\frac{|a-b|}{max(1,|b|)}\leq 10^{-4}
max(1,∣b∣)
∣a−b∣
≤10
−4
时,你的答案将被判定为正确。
示例1
输入
复制
3
0 0
2 0
0 2
输出
复制
2
说明
当在(0,0)(0,0)比赛时,到三个训练基地的最大距离是22。可以证明这是最小值。
思路:三分法,check函数找到当前X轴上的点距离基地的最大值,search函数找到距离最大中的最小
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
int n;
const double eps=1e-8;
int xx[N],y[N];
double check(double x)
{
double max=0;
for(int i=1;i<=n;i++)
{
double temp=y[i]*y[i]+(x-xx[i])*(x-xx[i]);
if(temp>max) max=temp;
}
return max;
}
double search(double l,double r)
{
double mid,midmid;
while(r-l>eps)
{
mid=l+(r-l)/2,midmid=mid+(r-mid)/2;
if(check(mid)>check(midmid)) l=mid;
else r=midmid;
}
return mid;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>xx[i]>>y[i];
double ans=search(-10000,10000);
printf("%.4lf",sqrt(check(ans)));
}
D 牛牛与牛妹的约会
添加链接描述
链接:https://ac.nowcoder.com/acm/contest/3006/D
来源:牛客网
牛牛在辛苦的一天的比赛之后,要去找牛妹玩,其实牛妹那天也在比赛。他为了找到牛妹,要尽快的从自己的比赛地到她的比赛地。
还记得吗,比赛地都是只在xx轴上的,所以两个人的坐标都满足y=0y=0。牛牛除了可以以11单位距离/单位时间的速度移动任意时间以外,还可以花费11单位时间进行闪现。每次闪现时,如果当前他的坐标是x=kx=k,他将闪现到x=\sqrt[3]{k}x=
3
k
的位置。
请帮他算算,最短需要多少时间,他可以找到牛妹~
输入描述:
输入数据包括多组用例,输入第一行包含一个数字T(1 \leq T \leq 5 \times 10^5)T(1≤T≤5×10
5
),表示数据组数。
接下来TT行,每行包括两个整数a,b(|a|,|b|\leq 10^6)a,b(∣a∣,∣b∣≤10
6
),表示牛牛所在的位置和牛妹所在的位置。
输出描述:
输出共TT行,每行包括一个实数,表示牛牛所花费的最短时间。
如果你的答案是aa,标准答案是bb,当|a-b|\leq 10^{-6}∣a−b∣≤10
−6
时,你的答案将被判定为正确。
示例1
输入
复制
2
3 -1
1 2
输出
复制
3.442249570
1.000000000
思路:贪心,直接比较闪现和走哪个更快即可。
#include<bits/stdc++.h>
using namespace std;
int a,b;
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>a>>b;
double ans=0;
double aa=a,bb=b,x=1.0/3.0;
while(1)
{
double an;
if(aa<0) an=-pow(-aa,x);
else an=pow(aa,x);
if(abs(an-bb)+1.0<abs(aa-bb))
{
ans+=1.0;
aa=an;
}
else
{
ans+=abs(aa-bb);
break;
}
}
printf("%.7lf\n",ans);
}
}
F 碎碎念
添加链接描述
链接:https://ac.nowcoder.com/acm/contest/3006/F
来源:牛客网
ACM比赛里,除了CE以外都是有效的提交。每一个提交都会有其评测的结果,或是AC,或是RJ(Rejected,包含各种不通过的情况)。往往一个人上去提交的时候,总有一个队友会坐在边上等着结果。那个人,往往都是只读题不写题的云选手~
牛牛战队里也有这样的云选手——牛能。当牛能看到有效提交得到了AC以后,都会大呼一声“你好能啊!”,反之,如果得到了RJ的话,就会化身为喷子,说xx句“你能不能行啊!”。大家比赛的都十分紧张,这样的大声呼喊未免会引起旁边队伍的注意。
当然牛牛战队交题的时候也很小心,一旦这一发出现了RJ,下一发有效提交一定能获得AC。
比赛结束了以后,旁边的一支队伍愤怒的跑过来说:你们比赛的时候吵不吵啊,一直在这大吼,吼了这么多句!
激烈的争吵引起了吃瓜群众的注意,吃瓜群众问道:吼了多少句啊,这么讨厌的吗
“啊……我也记不清了,大概是在[L,R][L,R]这个区间吧”
作为吃瓜群众的你,想根据这个信息算出,这个队伍有多少种有效提交结果序列的可能呢?
输入描述:
输入数据包括单组数据、多组询问。输入第一行包含一个整数x(2 \leq x \leq 100\,000)x(2≤x≤100000),表示牛能在RJ状态下会说“你能不能行啊!”的句子数量。
第二行包括一个整数Q(1 \leq Q \leq 10^5)Q(1≤Q≤10
5
),表示询问数量。
接下来QQ行,每行包括两个整数L,R(1 \leq L \leq R \leq 100\,000)L,R(1≤L≤R≤100000),表示每次询问下句子的区间数。
输出描述:
对于每组数据,在一行内输出一个整数,表示牛牛战队提交结果的可能性。由于结果可能很大,请对1\,000\,000\,0071000000007取模。
示例1
输入
复制
3
3
3 3
1 4
1 5
输出
复制
2
7
11
说明
第一组询问:可以是三个AC,或者一个RJ。
第二组询问:可以是1~4个AC,一个AC和一个RJ(共2种顺序),或者一个RJ。
第三组询问:可以有1~5个AC,两个AC和一个RJ(共3种顺序),一个AC和一个RJ(共2种顺序),或者一个RJ。
备注:
AC RJ AC AC 和 AC AC AC RJ 虽然都是3个AC,1个RJ,但是因为提交顺序的不同,视为不同种类。
思路:简单的DP,dp[i][1]表示说了i句话后AC,dp[i][0]表示说了i句话后RJ,①第i句AC的时候,不用官前面是什么情况。②第i句RJ的时候前面不可能再次RJ,且i>=x的时候才可能RJ。——>状态转移方程f[i][0] = (f[i - 1][0] + f[i - 1][1])。。。f[i][1] = f[i - x][0]。f[i][2]表示前缀和。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int q, n, x;
typedef long long ll;
ll f[N][4];
const int mod = 1e9 + 7;
int main()
{
ios::sync_with_stdio(0);
cin >> x;
mem(f, 0);
// f[i][0] 说了i句话,并且最后一次ac
// f[i][1] 说了i句话,并且最后一次rj
// 注意:rj之后必定ac
f[0][0] = 1;
f[0][1] = 0;
f[0][2] = 1;
for (int i = 1; i <= 100000; i++){
f[i][0] = (f[i - 1][0] + f[i - 1][1]) % mod;
if (i >= x){
f[i][1] = f[i - x][0];
f[i][1] %= mod;
}
}
for (int i = 1; i <= 100000; i++){
f[i][2] = (f[i - 1][2] + f[i][1] + f[i][0]) % mod;
}
cin >> q;
while (q--){
int l, r;
cin >> l >> r;
ll res = f[r][2] - f[l - 1][2];
res = (res + mod) % mod;
cout << res << "\n";
}
return 0;
}