牛客算法训练营5

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∣
​	
 ≤104
 时,你的答案将被判定为正确。

示例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∣≤106
 时,你的答案将被判定为正确。
示例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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值