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

    今天模拟了一套,被c题卡死了WCCCCCCCC。

    A - Alyona and copybooks

    题目大意:mike有 n 本书,他需要买到4的倍数本书,买一本书需要a元,二本b元,三本c元,

    问你最少需要多少钱。

    思路:水题,一共只有4种情况n对四 余 1,2,3,4。 枚举一下就好了。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll n,a,b,c;
    int main()
    {
        cin>>n>>a>>b>>c;
        ll ans=1e18;
        if(n%4==0)
        {
            ans=0;
        }
        else if(n%4==3)
        {
            ans=min(ans,a);
            ans=min(ans,3*c);
            ans=min(ans,b+c);
        }
        else if(n%4==2)
        {
            ans=min(ans,2*a);
            ans=min(ans,b);
            ans=min(ans,2*c);
        }
        else if(n%4==1)
        {
            ans=min(ans,c);
            ans=min(ans,3*a);
            ans=min(ans,a+b);
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    B - Alyona and flowers

    题目大意:有n个数,给你m个区间,让你选择若干个区间覆盖区间中的点,这些数的价值为

    各个数字与其覆盖次数乘积的和,问你价值最大是多少。

    思路:判断一个区间要不要覆盖就是,判断覆盖后整体的值是变大还是变小,这样思路就很

    明确了。

    #include<bits/stdc++.h>
    using namespace std;
    int w[105],cnt[105],sum[105];
    int n,m;
    int main()
    {
        cin>>n>>m;
    
        for(int i=1;i<=n;i++) scanf("%d",&w[i]),sum[i]=sum[i-1]+w[i];
        while(m--)
        {
            int l,r; scanf("%d%d",&l,&r);
            if(sum[r]-sum[l-1]>0)
            for(int i=l;i<=r;i++) cnt[i]++;
        }
        int ans=0;
        for(int i=1;i<=n;i++) ans+=cnt[i]*w[i];
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    C - Alyona and mex

    题目大意:有n个数,定义mex( l , r )运算为在l -> r 中未出现过的最小自然数,给你 m 个区间

    让你构造出这n个数,使mex值最小区间的值最大。

    妈的,疯狂宕机,我是猪脑子吧???!!!!

    我一直在考虑如何使每个区间都最优,就这样想了一个半小时,得出一个结论,这题我不会写,

    我他妈的******************************。

    思路:其实我们只需要将每个区间都保证其mex值大于等于最小的mex值,其中区间mex最小

    的最大值,肯定是其区间的长度,设这个值为x。所以我们只要保证所有区间mex大于等于x

    就行了,我们只需要从第一个数开始给他们赋值,0,1,……,x-1,这样一个循环赋值就好了。

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    int main()
    {
        cin>>n>>m;
        int mn=n;
        while(m--)
        {
            int l,r; scanf("%d%d",&l,&r);
            mn=min(mn,r-l+1);
        }
        int now=0;
        cout<<mn<<endl;
        for(int i=1;i<=n;i++)
        {
            cout<<now++<<" ";
            if(now==mn) now=0;
        }
        return 0;
    }
    View Code

    D - Alyona and a tree

    题目大意:给你一棵以 1 为根的树每棵树都有一个权值a[ i ],每条边也有一个权值e[ i ],一个

    节点u 管理 一个节点 v的条件是,1.  v 是 u 的子节点,2. 从 u 到 v 的所有边的权值和小于

    v 的权值和。 问你每个节点管理多少个节点。

    我感觉这题是个好题,我学到好多啊。

    思路:我们设 d( u ) 表示 1 到 u 边的权值和,那么 u 管理 v 可以表示成 d( v ) - d( u ) <= a[ v ]

    我们可以移项得到,d( v ) - a[ v ] <= d( u ),这样我们能保存路径,用lower_bound找到第一个

    小于d( v ) - a[ v ]的 d( u ),那样问题就变成了怎么更新,我们可以利用类似于前缀和的思想,

    用ans[ i ]来保存答案,是找到的那个 u 的ans[ u ]减去一,这样我们在回溯的时候,他的父节点

    及他的祖宗都减去一了,然后我们每次dfs下一个节点回来的时候,设当前节点为a,刚从节点

    b回溯回来,那么我们就 ans[ a ]+=ans[ b ]+1;这样我们通过继续回溯,就能将 a 的父节点及

    祖宗全部都加上一,可以这么想,如果没有之前的lower_bound找节点减去1,之后后边的

    加一,那么ans[ i ]的值就是,i 下面所有的子节点。

    #include<bits/stdc++.h>
    #define ll long long
    #define pii pair<ll,int>
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    using namespace std;
    const int N=2*1e5+5;
    vector<pii> e[N],r;//r 保存当前的路径。
    int n;
    ll a[N],ans[N],d[N];
    void dfs(int u)
    {
        r.pb(mk(d[u],u));
        int t=lower_bound(r.begin(),r.end(),mk(d[u]-a[u],-1))-r.begin()-1;
        if(t>=0) ans[r[t].se]--;//找到的点的ans-1,通过回溯,其上面的节点也都-1了。
        for(int i=0;i<e[u].size();i++)
        {
            pii v=e[u][i];
            d[v.se]=d[u]+v.fi;
            dfs(v.se);
            ans[u]+=ans[v.se]+1;//使u这个节点的ans加上v这个点的ans,回溯使u上面的节点都加上了v
        }
        r.pop_back();
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
        for(int i=2;i<=n;i++)
        {
            int p;
            ll w;
            scanf("%d%I64d",&p,&w);
            e[p].pb(mk(w,i));
        }
        dfs(1);
        for(int i=1;i<=n;i++) printf("%I64d%c",ans[i],i==n ? '
    ':' ');
        return 0;
    }
    View Code
  • 相关阅读:
    MVC5 Entity Framework学习之Entity Framework高级功能(转)
    js获取当前日期的前一天、一月、一年的日期 明天、后天(转)
    easyui datagrid 分页
    博客园技术精粹集合留贴
    常用C# DateTime 日期计算
    Jquery设置Cookie
    设计模式 -- 装饰者模式
    设计模式 -- 策略模式
    IBatis.Net中调用存储过程
    其他元素条件 IBatisNet
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7341184.html
Copyright © 2011-2022 走看看