「周练」Codeforces Round #530 (Div. 2)

一. Codeforces Round #530 (Div. 2)

比赛网址链接:Codeforces Round #530 (Div. 2)

A. Snowball (模拟)

题意

  一个重量为 w w w 的雪球从高度 h h h 滚下,每下降一单位,重量的增加量为当前高度,过程有两个石头,雪球经过石头重量的减少量为石头的重量,问雪球到达地面时的重量

思路

  按照题意模拟即可,注意过程重量不会减成负值

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#define ft first
#define sd second
#define nul string::npos
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=2e5+7;
const int inf=0x3f3f3f3f;
int w,h,u1,u2,d1,d2;

int main()
{
    cin>>w>>h>>u1>>d1>>u2>>d2;
    int pos=h,nw=w;
    while(pos){
        nw+=pos;
        if(pos==d1){
            nw-=u1;
            nw=max(nw,0);
        }
        else if(pos==d2){
            nw-=u2;
            nw=max(nw,0);
        }
        pos--;
    }
    cout<<nw<<'\n';
    return 0;
}

B. Squares and Segments (数学)

题意

  给一个数 n n n,找出两个数,使得它们的乘积不小于 n n n,要求最小化这两个数的和

思路

  开始读错题了,以为要用这 n n n 个小正方形组成一个矩形,后来发现不是,那就好办了,最小化两个数的和,肯定这两个数要比较接近,那就不断增大两个数,知道它们的乘积不小于 n n n 即可

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#define ft first
#define sd second
#define nul string::npos
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=2e5+7;
const ll inf=1e15;
ll n;

int main()
{
    cin>>n;
    ll sum=n+1;
    ll l=1,r=1;
    while(l*r<n){
        if(l>r)r++;
        else l++;
    }
    cout<<l+r<<'\n';
    return 0;
}

C. Postcard (贪心)

题意

  一个字符串里有小写字母、 ∗ * 符号、 ? ? ? 符号,这两种符号都可以将它们前方的字母删除、保留,不同的是 ∗ * 符号还可以无穷多次复制其前面的字母,问这个串能否构造出一个长度为 k k k 的串

思路

  首先考虑不存在的情况,那就只有两种情况,一是字符串里没有 ∗ * 符号,但 k k k 太大,二是 k k k 太小,能删的全删也构造不出长度为 k k k 的。
  之后就分类讨论就好,根据原串我们统计的信息,如果 k k k 比较大,那就确定好要复制的字母和个数,剩下的字母都保留即可,如果 k k k 比较小,那就确定要删除的字母个数,先删够,剩下的字母都保留即可

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#define ft first
#define sd second
#define nul string::npos
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=2e5+7;
const ll inf=1e15;
string s,ans;
int f1,f2,id=-1;
int n,sum[5];//sum[0]有意义的?和*个数、sum[1]无意义的*和?个数、sum[2]字母个数
int main()
{
    cin>>s>>n;
    int len=s.length();
    for(int i=0;i<len;i++){
        if(s[i]=='?'){
            if(i-1>=0&&(s[i-1]>='a'&&s[i-1]<='z')){
                sum[0]++;f1=1;
            }
            else sum[1]++;
        }
        else if(s[i]=='*'){
            if(i-1>=0&&(s[i-1]>='a'&&s[i-1]<='z')){
                id=i;sum[0]++;f2=1;
            }
            else sum[1]++;
        }
        else sum[2]++;
    }
    int x=sum[2]-sum[0]-sum[1];
    if((n>sum[2]&&!f2)||(n<x)){//太多或太少
        puts("Impossible");return 0;
    }
    if(n>=sum[3]){//太多的情况
        ans="";
        int ln=n-sum[2];
        for(int i=0;i<id;i++){
            if(s[i]>='a'&&s[i]<='z')ans+=s[i];
        }
        for(int i=1;i<=ln;i++)ans+=s[id-1];
        for(int i=id+1;i<len;i++){
            if(s[i]>='a'&&s[i]<='z')ans+=s[i];
        }
        cout<<ans<<'\n';return 0;
    }
    int sc=sum[2]-n;
    for(int i=0;i<len;i++){
        if(s[i]>='a'&&s[i]<='z'){
            if(i+1<len&&(s[i+1]=='*'||s[i+1]=='?')){
                if(sc){
                    sc--;
                }
                else ans+=s[i];
                i++;
            }
            else {
                ans+=s[i];
            }
        }
        else continue;
    }
    cout<<ans<<'\n';
    return 0;
}

D. Sum in the tree (dfs+贪心)

题意

  现在有一棵树,根为 1 1 1 i i i 号结点的权值为 a i a_i ai s i s_i si i i i 号结点到根路径上的总权值,现在只知道深度为奇数的结点的 s i s_i si 值,让你推出 所有结点的 a i a_i ai 值,要求它们的 a i a_i ai 总和最小

思路

  我们会发现一个规律就是,给越靠近根的结点赋值越大,它们的子孙赋值就越小,那么 a i a_i ai 总和就会越小,所以我们要想办法把靠近根的结点赋上尽可能大的值,离根越远的赋尽可能小的值
  对于 − 1 -1 1 的情况肯定就是对于某一个结点,存在一个子孙结点的 s i s_i si 值比其本身的要小,因为 a i a_i ai 非负,所以从根到叶子的路径 s i s_i si 值肯定不会递减。然后我们尝试还原深度为偶数的每个点的 s i s_i si 值。
  根据前面的分析,很容易得出 s u = m i n ( s v ) ( v 是 u 的 儿 子 ) s_u=min(s_v)(v是u的儿子) su=min(sv)(vu),也就是儿子共享的部分,这部分给父亲,让父亲赋更大的值,如果叶子所在层也为偶数层的话其 a i a_i ai 值显然赋 0 最优,所以其 s i s_i si 的值应和父亲的相同,知道了所有结点的 s i s_i si 值, a i a_i ai 就很好求了

代码

#include <bits/stdc++.h>
#define ft first
#define sd second
#define pb push_back
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=1e5+7;
const int inf=0x3f3f3f3f;
int n,flag=0;
ll a[maxn],s[maxn];
int dep[maxn];
vector<int> g[maxn];
ll dfs(int u,int fa,ll ma){//ma为父亲的s[]值
    dep[u]=dep[fa]+1;
    ll qq=inf;
    if(s[u]!=-1){
        if(s[u]<ma)flag=1;
        else ma=s[u];
    }
    for(auto v: g[u]){
        if(v==fa)continue;
        qq=min(dfs(v,u,ma),qq);
    }
    if(s[u]==-1&&qq!=inf)s[u]=qq;//是否为叶子
    if(s[u]==-1&&qq==inf)s[u]=ma;
    return s[u];
}
void _dfs(int u,int fa,ll ma){
    a[u]=s[u]-ma;
    ma=s[u];
    for(auto v: g[u]){
        if(v==fa)continue;
        _dfs(v,u,ma);
    }
}
int main()
{
    scanf("%d",&n);
    for(int u=2,v;u<=n;u++){
        scanf("%d",&v);
        g[u].pb(v);
        g[v].pb(u);
    }
    for(int i=1;i<=n;i++)scanf("%lld",&s[i]);
    dfs(1,0,0);
    if(flag){
        puts("-1");return 0;
    }
    _dfs(1,0,0);
    ll sum=0;
    for(int i=1;i<=n;i++){
        sum+=a[i];
    }
    cout<<sum<<'\n';
    return 0;
}

E. Nice table (找规律+模拟)

题意

  一个 n × m n×m n×m 矩阵,要求最小的修改次数使得矩阵的所有 2 × 2 2×2 2×2 的子矩阵都包含 A , T , G , C A,T,G,C A,T,G,C 四个字母

思路

找规律会发现有两种情况:

  1.每行都是两个固定字符交替组成,且相邻两行的字符交集为空
例如:
在这里插入图片描述
  2.每列都由两个固定字符交替组成,且相邻两列的字符交集为空
例如:
在这里插入图片描述
那就枚举交替的行或列,找出替换最小的那组

代码

#include <bits/stdc++.h>
#define ft first
#define sd second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=3e5+7;
const double inf=1e18;
int n,m,hid,lid;
string s[maxn];
char str[6][2]={{'A','T'},{'A','C'},{'A','G'},{'C','T'},{'T','G'},{'C','G'}};
int h[6][maxn][2],hsum[6];
int l[6][maxn][2],lsum[6];
string ans[maxn];
void solve(int op,int id){
    if(!op){//行
        for(int i=0;i<n;i++){
            if(h[id][i][0]!=-1){
                for(int j=0;j<m;j++){
                    printf("%c",str[(i&1)?5-id:id][j&1]);
                }
            }
            else {
                for(int j=0;j<m;j++){
                    printf("%c",str[(i&1)?5-id:id][!(j&1)]);
                }
            }
            printf("\n");
        }
        return;
    }
    for(int i=0;i<m;i++){//列
        if(l[id][i][0]!=-1){
            for(int j=0;j<n;j++){
                ans[j]+=str[(i&1)?5-id:id][j&1];
            }
        }
        else {
            for(int j=0;j<n;j++){
                ans[j]+=str[(i&1)?5-id:id][!(j&1)];
            }
        }
    }
    for(int i=0;i<n;i++)cout<<ans[i]<<'\n';
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)cin>>s[i];
    memset(h,-1,sizeof(h));
    memset(l,-1,sizeof(l));
    for(int i=0;i<6;i++){//枚举行
        int sum=0;
        for(int j=0;j<n;j++){
            int a=0,b=0;
            for(int k=0;k<m;k++){
                if(s[j][k]!=str[(j&1)?5-i:i][k&1])a++;
                if(s[j][k]!=str[(j&1)?5-i:i][!(k&1)])b++;
            }
            if(a>=b)h[i][j][1]=b,sum+=b;//逆序
            else h[i][j][0]=a,sum+=a;//正序
        }
        hsum[i]=sum;
        if(hsum[hid]>hsum[i])hid=i;//保留最优解下标
    }
    for(int i=0;i<6;i++){//枚举列
        int sum=0;
        for(int j=0;j<m;j++){
            int a=0,b=0;
            for(int k=0;k<n;k++){
                if(s[k][j]!=str[(j&1)?5-i:i][k&1])a++;
                if(s[k][j]!=str[(j&1)?5-i:i][!(k&1)])b++;
            }
            if(a>=b)l[i][j][1]=b,sum+=b;//逆序
            else l[i][j][0]=a,sum+=a;//正序
        }
        lsum[i]=sum;
        if(lsum[lid]>lsum[i])lid=i;//保留最优解下标
    }
    if(hsum[hid]<lsum[lid])solve(0,hid);//行
    else solve(1,lid);//列
    return 0;
}

F. Cookies (树形dp+线段树)

题意

  给你一棵树,树上有 n n n 个节点,每个节点上有 x i x_i xi 块饼干,吃在这个节点上的每块饼干需要花费的时间为 t i t_i ti,有两个玩家,玩家一每次的操作是:移动到当前点的子节点或者申请游戏结束返回根节点并选择性的吃沿途的饼干,玩家二的操作是:在玩家一操作后删除当前点到儿子节点的一条边,走路和吃饼干都消耗时间,会给出一个总时间,在总时间内尽可能的多吃饼干,问最多能吃多少个?

思路

  首先我们可以维护出玩家一在每个结点返回所能吃的最大饼干数,设 f u f_u fu 为玩家一在 u u u 号结点结束游戏返回根所能吃到的最多饼干数,为什么可以维护呢?因为固定结点时,其到根的距离所花时间我们可以很容易求出来,然后 总时间减去路径花费时间的两倍(去和返) 剩下的时间即为玩家一可以在返回路径上吃饼干的时间,最优策略肯定是先吃这个路径上单位花时间少的饼干,吃完再吃次小的…依次类推,暴力去路径找的花太费时,所以可以选择合适的数据结构来维护路径上饼干的信息,可以用线段树,开始想用树状数组来着,但是遇到了问题,因为玩家一可能在一个节点只吃部分饼干,用线段树的话就 依照饼干所花时间建立线段树,线段树结点维护两个信息,一个是这个结点所维护的时间段吃掉所有饼干所需花费的总时间,一个是这个时间段的饼干总个数
  下一步,我们不妨定义: d p u dp_u dpu 从结点 u u u 向下走最多可以吃到多少饼干,由于是玩家一先手,那么最开始的最大边则不会被删除,但之后路途的最大边都会被玩家二删除,所以很容易得到递推式:
d p u = m a x ( f u , d p v ) ( u 为 根 , v 为 u 的 儿 子 且 d p v 为 u 儿 子 中 最 大 的 那 个 ) dp_u=max(f_u,dp_v)(u为根,v为u的儿子且dp_v为u儿子中最大的那个) dpu=max(fu,dpv)(u,vudpvu)
d p u = m a x ( f u , d p v ) ( u 非 根 , v 为 u 的 儿 子 且 d p v 为 u 儿 子 中 次 大 的 那 个 ) dp_u=max(f_u,dp_v)(u非根,v为u的儿子且dp_v为u儿子中次大的那个) dpu=max(fu,dpv)(u,vudpvu)
  值得注意的是: d p u = f u ( u 为 叶 子 ) dp_u=f_u(u为叶子) dpu=fu(u)
d p 1 即 为 最 终 结 果 dp_1即为最终结果 dp1
代码

#include <bits/stdc++.h>
#define ft first
#define sd second
#define pb push_back
#define ls p<<1
#define rs p<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<int,ll> P;
const int maxn=1e5+7;
const int N=1e6+7;
const int inf=0x3f3f3f3f;
int n,m,siz;
ll T;
ll x[maxn],t[maxn];
ll f[maxn],dp[maxn];
vector<P> g[maxn];
ll a[N<<2],b[N<<2];
void up(int p){
    a[p]=a[ls]+a[rs];
    b[p]=b[ls]+b[rs];
}
void update(int x,ll v,int l,int r,int p){
    if(l==r){
        b[p]+=v;//维护个数
        a[p]+=v*x;//维护总时间
        return;
    }
    int m=(l+r)>>1;
    if(x<=m)update(x,v,lson);
    else update(x,v,rson);
    up(p);
}
ll query(ll v,int l,int r,int p){
    int m=(l+r)>>1;
    if(a[p]<=v)return b[p];
    if(l==r)return v/l;//可能只吃部分,因为时间不够
    ll res=0;
    if(a[ls]>=v)res=query(v,lson);
    else res=b[ls]+query(v-a[ls],rson);
    return res;
}
void dfs(int u,int fa,ll s){
    update(t[u],x[u],1,siz,1);
    f[u]=query(T-s*2,1,siz,1);
    for(auto no: g[u]){
        int v=no.ft;
        ll w=no.sd;
        if(fa==v)continue;
        if(T-(s+w)*2<=0)continue;//时间不够不用继续往下走了
        dfs(v,u,s+w);
    }
    update(t[u],-x[u],1,siz,1);//回溯要删除
}
void _dfs(int u,int fa){
    int son=0;
    ll f1=0,f2=0;//f1最大,f2次大
    for(auto no: g[u]){
        int v=no.ft;
        if(fa==v)continue;
        _dfs(v,u);
        son++;
        if(dp[v]>f1){
            f2=f1;f1=dp[v];
        }
        else if(dp[v]>f2)f2=dp[v];
    }
    if(!son)dp[u]=f[u];
    else if(u==1)dp[u]=max(f[u],f1);
    else dp[u]=max(f[u],f2);//非根最大会被玩家二删除
}
int main()
{
    cin>>n>>T;
    for(int i=1;i<=n;i++)scanf("%lld",&x[i]);
    for(int i=1;i<=n;i++)scanf("%lld",&t[i]),siz=max(siz,(int)t[i]);
    for(int i=2,p;i<=n;i++){
        ll l;
        scanf("%d%lld",&p,&l);
        g[p].pb(P(i,l));
        g[i].pb(P(p,l));
    }
    dfs(1,0,0);//求f[i]
    _dfs(1,0); //求dp[i]
    printf("%lld\n",dp[1]);
    return 0;
}

二. 二分练习

A. Aggressive cows (最大化最小值)

题目链接

POJ 2456

题意

x x x 坐标轴有 n n n 个牛舍,现在给 m m m 头牛分配牛舍,问怎样分配使得任意两头牛的距离最大化

思路

  二分一下任意两头牛的最小距离,从前往后贪心的填即可

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ft first
#define sd second
#define nul string::npos
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=2e5+7;
const int inf=0x3f3f3f3f;
int t,n,c;
int a[maxn];
bool judge(int x){
    int pos=a[0];
    int co=1;
    for(int i=1;i<n;i++){
        if(a[i]-pos<x)continue;
        else {
            co++;
            pos=a[i];
        }
    }
    return co>=c;
}
int main()
{
    cin>>n>>c;
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    sort(a,a+n);
    int l=0,r=inf,ans=1;
    while(l<=r){
        int m=(l+r)>>1;
        if(judge(m)){
            l=m+1;ans=m;
        }
        else r=m-1;
    }
    cout<<ans<<'\n';
    return 0;
}

B. String Game (二分下标)

题目链接

CodeForces - 779D

题意

  一个字符串 s s s,现在有一个删除序列,问按照这个删除序列执行,最多执行几次,原序列仍有 t t t 字符串的子序列

思路

  二分这个删除序列的下标,看以这个下标为终点对 s s s 串进行删除,剩下的串能否找出一个子序列为 t t t

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#define ft first
#define sd second
#define nul string::npos
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=2e5+7;
const int inf=0x3f3f3f3f;
int n,c,len1,len2;
int a[maxn];
bool vis[maxn];
string s,t;
bool judge(int m){
    ms(vis,0);
    int len=min(m,len1);
    for(int i=1;i<=len;i++){
        vis[a[i]]=1;
    }
    string no="";
    for(int i=0;i<len1;i++){
        if(!vis[i+1]){
            no+=s[i];
        }
    }
    len=no.length();
    int l=0;
    for(int i=0;i<len;i++){
        if(l==len2)break;
        if(no[i]==t[l])l++;
    }
    return l==len2;
}
int main()
{
    cin>>s>>t;
    len1=s.length();
    len2=t.length();
    for(int i=1;i<=len1;i++)scanf("%d",&a[i]);
    int l=0,r=len1+1,ans=0;
    while(l<=r){
        int m=(l+r)>>1;
        if(judge(m)){
            l=m+1,ans=m;
        }
        else r=m-1;
    }
    ans=min(ans,len1);
    cout<<ans<<'\n';
    return 0;
}

C. Delivering Carcinogen (二分+计算几何)

题目链接

CodeForces - 199E

题意

  有一颗行星 P P P 围绕一颗恒星 D D D 以恒定速度 v p v_p vp 逆时针旋转,绕行半径为 R R R,现在有一艘飞船(初始位置给出)要去 行星 P P P 上,且要求任何时刻都不能处在 以恒星 D D D 为中心,半径为 r r r 的范围内,让你求到达行星 P P P 的最短时间

思路

  对于一个确定时间 t t t,行星的位置确定,飞船到达行星的时间取决于其运行路线,如果以最短路线前往 P P P,花费时间为 t 1 t_1 t1,只要 t 1 t_1 t1 不大于 t t t,就一定可以到达 P P P,所以可以对时间二分,来寻找最短时间。

对于确定的时间 t t t,现在有几个问题需要解决:

  1. 给出行星的初始坐标,经过时间 t t t 后的具体坐标
  2. 确定行星的位置后,飞船的最短距离的确定与计算

(1) 对于前者,确定其逆时针旋转多少度即可
推导过程如下:
在这里插入图片描述
设原向量 p 1 p_1 p1 坐标 ( x 1 , y 1 ) (x_1,y_1) (x1,y1),长度为 R R R ,与 x x x 轴夹角为 A A A,逆时针旋转 B B B 角度后的坐标为 ( x 2 , y 2 ) (x_2,y_2) (x2,y2),则有:
x 2 = R c o s ( A + B ) x_2=Rcos(A+B) x2=Rcos(A+B)
= R c o s ( A ) c o s ( B ) − R s i n ( A ) s i n ( B ) =Rcos(A)cos(B)-Rsin(A)sin(B) =Rcos(A)cos(B)Rsin(A)sin(B)
= x 1 c o s ( B ) − y 1 s i n ( B ) =x_1cos(B)-y_1sin(B) =x1cos(B)y1sin(B)
y 2 y_2 y2 同理:
y 2 = R s i n ( A + B ) y_2=Rsin(A+B) y2=Rsin(A+B)
= R s i n ( A ) c o s ( B ) + R c o s ( A ) s i n ( B ) =Rsin(A)cos(B)+Rcos(A)sin(B) =Rsin(A)cos(B)+Rcos(A)sin(B)
= y 1 c o s ( B ) + x 1 s i n ( B ) =y_1cos(B)+x_1sin(B) =y1cos(B)+x1sin(B)
(2) 对于后者,比较麻烦。要先确定是否可以直线到达,或者是中间需要绕着走,这取决于 飞船与行星的距离两者关于内圆的切线段长度和 谁大谁小
在这里插入图片描述
在这里插入图片描述
  直线走的话就直接拿两点距离除以飞船速度可得最短时间,如果需要绕行的话,需要计算中间那段绕内圆的弧长,弧度的计算是先计算 飞船与行星关于原点的夹角 ,可根据余弦定理来求(飞船 行星和原点组成一个三角形,知道三边可求任意夹角),然后计算 飞船与切点关于圆心的夹角行星与切点关于圆心的夹角,这个很好求。然后求得的大角减去两个小角即为我们要的那段弧的弧度,乘上半径即为距离。
在这里插入图片描述
代码

#include <bits/stdc++.h>
#define ft first
#define sd second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=2e5+7;
const double inf=1e18;
const double eps=1e-8;
const double pi=acos(-1.0);
double xp,yp,vp,x,y,v,r;
double tp,R;

bool c(double t){
    double a=(t-(int)(t/tp)*tp)*pi*2/tp;//行星在t时刻需要逆时针旋转的角度
    double nxp=xp*cos(a)-yp*sin(a);//行星的x坐标
    double nyp=yp*cos(a)+xp*sin(a);//行星的y坐标
    double T=0.0;//飞船沿最短路走花费总时长
    double dis1=sqrt(x*x+y*y-r*r);//飞船与内圆的切线长度
    double dis2=sqrt(nxp*nxp+nyp*nyp-r*r);//星球与内圆的切线长度
    double dis3=sqrt(x*x+y*y);//飞船到原点的距离
    double dis4=sqrt(nxp*nxp+nyp*nyp);//行星到原点的距离 就是 R
    double dis=sqrt((x-nxp)*(x-nxp)+(y-nyp)*(y-nyp));//飞船与行星的距离
    if(dis1+dis2>=dis)T=dis/v;//不需要绕行
    else {//需要绕行
        //余弦定理求大角
        double angle=acos((dis3*dis3+dis4*dis4-dis*dis)/(dis3*dis4*2));
        double angle1=atan(dis1/r);//飞船的小角
        double angle2=atan(dis2/r);//行星的小角
        angle-=angle1+angle2;
        T=(dis1+dis2+angle*r)/v;
    }
    return T<=t;
}
int main()
{
    cin>>xp>>yp>>vp>>x>>y>>v>>r;
    R=sqrt(xp*xp+yp*yp);
    tp=pi*R*2.0/vp;//行星周期
    double l=0.0,r=inf,ans=0;
    for(int i=1;i<=100;i++){
        double m=(l+r)/2.0;
        if(c(m)){
            r=m;ans=m;
        }
        else l=m;
    }
    printf("%.10f\n",ans);
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值