• Codeforces Round #407 (Div. 2)


    来自FallDream的博客,未经允许,请勿转载,谢谢。

    ------------------------------------------------------

    A.Anastasia and pebbles

    你有两个口袋,每种口袋最多只能装k个物品,有n种物品,每种物品有ai个,两种不同的物品不能混在一起,问最少要装多少次.

    题解:.............

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<map>
    #define ll long long
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    ll n,k;
    ll ans=0;
    
    int main()
    {
        n=read();k=read();
        for(int i=1;i<=n;i++)
        {
            ll x=read();
            ans+=(x+k-1)/k;
        }
        cout<<(ans+1)/2;
        return 0;
    }

    B.Masha and geometric depression
    给定一个等比数列,第一项是b1,之后每一项是前一项乘以q,但是b1和q都可以是负数或0。你还有m个不吉利的数字。每当满足abs(b)<=l的时候,你会把b写出来,除非它是一个不吉利的数字。

    问你会写出多少个数字,当然你可能写出无限多的数字。

    题解:大判断。  一开始我以为不满足还能继续写....结果pretest WA了一排...

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<map>
    #define ll long long
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    int b1,q,l,m;
    map<int,bool> mp;
    
    inline int abs(int x){return x<0?-x:x;}
    
    int main()
    {
        b1=read();q=read();l=read();m=read();
        if(abs(b1)>l) return 0*puts("0");
        for(int i=1;i<=m;i++)mp[read()]=1;
        if(b1==0)
        {
            if(mp[0])return 0*puts("0");
            else return 0*puts("inf");
        }
        if(q==0)
        {
            if(!mp[0])return 0*puts("inf");
            if(abs(b1)<=l&&!mp[b1]) return 0*puts("1");
            puts("0");
            return 0;
        }
        if(q==1)
        {
            if(abs(b1)<=l&&!mp[b1])return 0*puts("inf");
            else return 0*puts("0");
        }
        if(q==-1)
        {
            int ans=0;
            if(abs(b1)<=l&&!mp[b1])ans++;
            if(abs(b1)<=l&&!mp[-b1]) ans++;
            if(ans) return 0*puts("inf");
            else return 0*puts("0");
        }
        else
        {
            int ans=(abs(b1)>l||mp[b1])?0:1;
            while(1LL*abs(q)*abs(b1)<=(ll)l)
            {
                b1*=q;
                if(abs(b1)<=l&&!mp[b1])ans++;
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    C.Functions again

    给定一个数字序列ai和函数f,求f的最大值。  $nleqslant 100000$

     题解:发现每一种$|a[i]-a[i+1]|$只有两种不同的贡献,分开计算即可。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define INF 1000000000
    #define MN 100000000
    using namespace std;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    int n;
    int a[100005];
    ll f[100005],f2[100005];
    ll ans=0;
    int abs(int x){return x<0?-x:x;}
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)a[i]=read();
        for(int i=1;i<=n;i++) f[i]=f[i-1]+1LL*(i&1?1:-1)*abs(a[i]-a[i+1]);
        for(int i=1;i<=n;i++) f2[i]=f2[i-1]+1LL*(i&1?-1:1)*abs(a[i]-a[i+1]);
        ll minn=0;
        for(int i=1;i<n;i++)
        {
            ans=max(ans,f[i]-minn);
            if(i%2==0)minn=min(minn,f[i]);
        }
        minn=f2[1];
        for(int i=2;i<n;i++)
        {
          //  cout<<i<<" "<<f2[i]<<" "<<ans<<" "<<minn<<endl;
            ans=max(ans,f2[i]-minn);
            if(i&1)minn=min(minn,f2[i]);
        }
        cout<<ans<<endl;
        return 0;
    }

    D. Weird journey

    给定一个无向图,可能有自环,无重边,你要求出满足恰好有两条边只走了一次,其它都走了两次的路径数量。两种方案不同当且仅当边不同。  $n,mleqslant 10^{6}$

    题解:先判联通。然后我们把自环和普通边分开考虑。

    如果都选普通边,那么这两条边一定要有公共点,用度数计算一下即可。

    如果一个选自环,那么显然任意普通边都能成为另一条边。

    如果两个都选自环,那么显然没问题。

    #include<iostream>
    #include<cstdio>
    #define ll long long
    #define MN 1000000
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int n,m,cnt=0,head[MN+5],num=0,num2=0,s[MN+5];
    struct edge{int to,next;}e[MN*2+5];
    ll ans=0;
    bool mark[MN+5],b[MN+5];
    void ins (int f,int t){e[++cnt]=(edge){t,head[f]};head[f]=cnt;}
    
    void dfs(int x)
    {
        mark[x]=1;
        for(int i=head[x];i;i=e[i].next)
            if(!mark[e[i].to])
                dfs(e[i].to);
    }
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=m;i++) 
        {
            int u=read(),v=read();
            if(u==v) num2++,b[u]=1;
            else ins(u,v),ins(v,u),num++,s[u]++,s[v]++;
        }
        for(int i=1;i<=n;i++) 
            if(b[i]||head[i]) 
            {
                dfs(i);break;
            }
        for(int i=1;i<=n;i++) if(!mark[i]&&(head[i]||b[i])) return 0*puts("0");
        for(int i=1;i<=n;i++) ans+=1LL*s[i]*(s[i]-1)/2;
        ans+=1LL*num2*(m-num2)+1LL*num2*(num2-1)/2;
        printf("%lld",ans);
        return 0;
    }

    E. The Great Mixing

    给定n个数ai,你要从中选出最少的数,每个数可以选任意次,使得平均值等于k   $nleqslant 10^{6} , ai,kleqslant 1000$

    题解:显然n最多只有1000种,然后我们分成正的和负的考虑。我们发现我们选的数的总和不会超过$10^{6}$,所以直接bfs就可以了,复杂度不是满的,应该能比较快找出答案。

    数据挺水的,直接dp好像也能过。

    #include<iostream>
    #include<cstdio>
    #define MAXN 1000000 
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int n,k;
    bool mark[2005];
    int s[1005],q[MAXN+5],top=1,cnt=0,d[MAXN+5];
    
    int main()
    {
        k=read();n=read();
        for(int i=1;i<=n;i++)
        {
            int x=read()-k+1000;
            if(!mark[x]) mark[x]=1,s[++cnt]=x-1000;
        }
        d[0]=1;
        for(int i=1;i<=top;i++)
            for(int j=1;j<=cnt;j++)
            {
                if(s[j]+q[i]==0) return 0*printf("%d",d[q[i]]);
                if(s[j]+q[i]<=MAXN&&s[j]+q[i]>=0&&!d[s[j]+q[i]]) d[s[j]+q[i]]=d[q[i]]+1,q[++top]=s[j]+q[i];
            }
        puts("-1");
        return 0;
    }
  • 相关阅读:
    Python开发入门与实战3-Django动态页面
    Python开发入门与实战2-第一个Django项目
    Python开发入门与实战1-开发环境
    牛客网剑指offer第12题——数值的整数次方
    再叙快速排序
    牛客网剑指offer第29题——最小的k个数
    牛客网剑指offer第59题——按之字形顺序打印二叉树
    牛客网剑指offer第33题——第N个丑数
    各种特征距离的计算方法及应用
    牛客网剑指offer第24题——二叉树中和为某一值的路径
  • 原文地址:https://www.cnblogs.com/FallDream/p/codeforces407.html
Copyright © 2020-2023  润新知