zoukankan      html  css  js  c++  java
  • Codeforces Round #370 (Div. 2)

    A - Memory and Crow

    这题我没看题意,看了样例猜了一下就AC了,题目好像还挺复杂的。

    #include<bits/stdc++.h>
    using namespace std;
    int a[100005];
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<n;i++) printf("%d ",a[i]+a[i+1]);
        printf("%d
    ",a[n]);
        return 0;
    }
    View Code

     B - Memory and Trident

    题目大意:一个人可以往上下左右走,给你一串操作,问你最少改变几个能回到原地。

    思路:将上下分成一堆,左右分成一堆,改变的时候优先同一堆里面的互换。这样能

    保证次数最少。代码写的有点搓。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    char s[N];
    int vis[4];
    int main()
    {
        scanf("%s",s);
        int len=strlen(s);
        if(len%2)
        {
            puts("-1");
            return 0;
        }
        for(int i=0;i<len;i++)
        {
            if(s[i]=='U') vis[0]++;
            else if(s[i]=='D') vis[1]++;
            else if(s[i]=='L') vis[2]++;
            else vis[3]++;
        }
        if((vis[0]+vis[1])%2==0)
        {
            int a=(vis[0]+vis[1])/2-min(vis[0],vis[1]);
            int b=(vis[2]+vis[3])/2-min(vis[2],vis[3]);
            cout<<a+b<<endl;
        }
        else
        {
            int a=(vis[0]+vis[1]-1)/2-min(vis[0],vis[1]);
            //cout<<a<<endl;
            int b=(vis[2]+vis[3]-1)/2-min(vis[2],vis[3]);
            cout<<a+b+1<<endl;
        }
        return 0;
    }
    View Code

    C - Memory and De-Evolution

    题目大意:给你两个边长分别为x和y的等边三角形,问你最少通过多少次改变可以把x变成y(x>y)

    每次改变可以改变一条边,且改变后三边依旧能构成三角形。

    思路:想了一会就想出来了,反过来模拟,从y模拟到x,每次y都取出最小的边把它变成能变成

    的最大值,等到最小的边都大于x了就结束。

    #include<bits/stdc++.h>
    using namespace std;
    int x,y;
    int a[3];
    int main()
    {
        cin>>x>>y;
        a[0]=a[1]=a[2]=y;
        int i=0;
        int ans=0;
        for(;;i++)
        {
            ans++;
            a[i%3]=a[(i+1)%3]+a[(i+2)%3]-1;
            //printf("%d %d %d
    ",a[0],a[1],a[2]);
            if(min(a[(i+1)%3],a[(i+2)%3])>=x) break;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    D - Memory and Scores

    题目大意:两个人有初试分数a和b,有 t  轮游戏,每轮游戏每人随机得到[-k,k]中的一个数加

    到自己的分数中,问你k轮以后,有多少个结果是 第一个人得分数大于第二个人的。结果对1e9+7取模。

    思路:用dp[i][j] 表示进行到 i 轮,分数为得到的分数为j 的方案数。

    状态转移方程,dp[i][j]=dp[i-1] [j-k]+dp[i-1][j-k+1]+...+dp[i-1][j+k]。

    直接这样写可能会超时,我们考虑用前缀和优化,即每一轮更新

    的时候保存当前轮dp的前缀和,用于更新下一轮。最后就是计算

    方案总数的问题了。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2*1e5+1;
    ll dp[101][N],a[N],b[N];
    ll x,y,k,t;
    const ll mod=1e9+7;
    int main()
    {
        cin>>x>>y>>k>>t;
        ll up=k*t*2;
        dp[0][k*t]=1;
        for(ll i=0;i<=up;i++)
        {
            if(i==0) a[i]=dp[0][i];
            else a[i]=a[i-1]+dp[0][i];
        }
        ll *p=a,*q=b,*g;
        for(ll i=1;i<=t;i++)
        {
            for(ll j=0;j<=up;j++)
            {
                ll l=j-k,r=j+k;
                l=max((ll)0,l);r=min(up,r);
                ll t=dp[i][j];
                if(l==0) dp[i][j]=(dp[i][j]+p[r])%mod;
                else dp[i][j]=(dp[i][j]+p[r]-p[l-1]+mod)%mod;
                if(j==0) q[j]=dp[i][j]%mod;
                else q[j]=(dp[i][j]+q[j-1])%mod;
            }
            g=q;
            q=p;
            p=g;
        }
        ll ans=0;
        ll dis=y-x+1;
        for(ll i=0;i<=up;i++)
        {
            ll now=i-dis;
            if(now>up) now=up;
            if(now>=0) ans=(ans+((dp[t][i])*p[now])%mod)%mod;
        }
    
        cout<<ans%mod<<endl;
        return 0;
    }
    View Code

    E - Memory and Casinos

    题目大意:有n个赌场,每个赌场你赢的概率为p,如果赢了你往右边的赌场走,输了往左边的赌场走,

    给你一个范围 l 到 r 问你从 l 开始,最后在 r 赢且不在 l 输的概率是多少,写的时候真的不知道怎么写。。

    还是太菜了。

    思路:我们可以用线段树进行区间合并,我们记L( l , r )为从 l 开始最后在r赢不在且在 l 永远不输的概率,

    R( l , r )为从 r 开始,最后在 r 赢,且永远不在 l 输的概率。我们对线段树的每个节点保存当前区间的这

    两个值,每个节点保存该区间的 L 和 R 值。那么两个区间该如何合并呢?

    我们可以先考虑只有两个点的情况 a 点和 b 点,求从 a 开始,最终在 b 点赢,且在 a 点永远不输的概率,

    且 在 a 点赢的概率为p1,b 点为 p2,那么我们可以知道我们要求的概率就是一下式子的和

    p1*p2         a(win)   b(win)

    p1 * ( ( 1 - p2 ) * p1 ) * p2        a(win) b(lose) a(win) b(win)

    p1 * ( ( 1 - p2 ) * p1)^2 * p2     a(w) ( b(l)  a(w)  b(l)  a(w) ) b(w)

    .............

    p1 * ( ( 1 - p2 ) * p1)^n * p2

    求和就是等比数列求和。

    那么对于两个区间也是同理,对于两个区间a,b,他们的L,R分别为  L1 , L2 , R1  R2,合并之后的 L 为 L3  R 为 R3

    那么 L3 为以下式子的和

    L1 * L2

    L1 * ( ( 1 - L2 ) * R1 ) * L2

    L1 * ( ( 1 - L2 ) * R1 )^2  * L2

    ............

    L1 * ( ( 1 - L2 ) * R1 ) ^n * L2

    R3 为以下式子的和

    R2

    ( 1 - R2 ) * R1 * L2

    ( 1 - R2 ) * R1 *( ( 1 - L2 ) * R1 ) * L2

    ( 1 - R2 ) * R1 *( ( 1 - L2 ) * R1 )^2 * L2

    .............

    ( 1 - R2 ) * R1 *( ( 1 - L2 ) * R1 )^n * L2

    这样就能完成线段树的区间合并了。

    #include<bits/stdc++.h>
    #define pdd pair<double,double>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    const int N=1e5+5;
    pdd st[N<<2];
    int n,q;
    pdd Merge(pdd x,pdd y)
    {
        pdd ans;
        ans.fi=(x.fi*y.fi)/(1.0-x.se*(1.0-y.fi));
        ans.se=y.se+((1.0-y.se)*x.se*y.fi)/(1.0-(1.0-y.fi)*x.se);
        return ans;
    }
    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            double a,b;
            scanf("%lf%lf",&a,&b);
            st[rt].fi=a/b; st[rt].se=a/b;
            return;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        st[rt]=Merge(st[ls],st[rs]);
    }
    void updata(int l,int r,int rt,int x,double a,double b)
    {
        if(l==r && r==x)
        {
            st[rt].fi=a/b;st[rt].se=a/b;
            return;
        }
        int m=(l+r)>>1;
        if(x<=m) updata(lson,x,a,b);
        else updata(rson,x,a,b);
        st[rt]=Merge(st[ls],st[rs]);
    }
    pdd query(int L,int R,int l,int r,int rt)
    {
        if(l>=L && r<=R) return st[rt];
        int m=(l+r)>>1;
        if(R<=m) return query(L,R,lson);
        else if(L>m) return query(L,R,rson);
        else return Merge(query(L,R,lson),query(L,R,rson));
    }
    int main()
    {
        cin>>n>>q;
        build(1,n,1);
        while(q--)
        {
            int op;
            scanf("%d",&op);
            if(op==1)
            {
                int  x;
                double a,b;
                scanf("%d%lf%lf",&x,&a,&b);
                updata(1,n,1,x,a,b);
            }
            else
            {
                int l,r;
                scanf("%d%d",&l,&r);
                pdd ans=query(l,r,1,n,1);
                printf("%.12f
    ",ans.fi);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    null in ABAP and nullpointer in Java
    SAP ABAP SM50事务码和Hybris Commerce的线程管理器
    Hybris service layer和SAP CRM WebClient UI架构的横向比较
    SAP ABAP和Linux系统里如何检查网络传输的数据量
    SAP CRM WebClient UI和Hybris的controller是如何被调用的
    SAP CRM和Cloud for Customer订单中的业务伙伴的自动决定机制
    SAP CRM WebClient UI和Hybris CommerceUI tag的渲染逻辑
    SAP BSP和JSP页面里UI元素的ID生成逻辑
    微信jsapi支付
    微信jsapi退款操作
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7240669.html
Copyright © 2011-2022 走看看