zoukankan      html  css  js  c++  java
  • 【CF-1371 C-E2】

    Codeforces Round #654 (Div. 2)

    C.

    题意

    有 a 个香草饼干和 b 个巧克力饼干,以及两种类型的客人:

    1. 如果香草饼干的数量 > 巧克力饼干的数量,那么他会吃掉香草饼干,否则会吃掉巧克力饼干
    2. 如果巧克力饼干的数量 < 香草饼干的数量,那么他会吃掉巧克力饼干,否则会吃掉香草饼干

    有 n 个 1 类型的客人,m 个 2 类型的客人,问是否可以满足这些客人的要求。

    思路

    简言之,就是 1 类型的人吃多的,2 类型的人吃少的。

    如果最少的饼干数量比 2 类型人还少,或者饼干总数没有人数多,肯定无法满足所有客人的要求。

    如果最少的饼干数量大于 2 类型的人,那么先让 1 类型的人吃,直到满足 1 类型的所有人或者最少的饼干数量等于 2 类型的人,这时让所有 2 类型的人吃,再让所有 1 类型的人吃。

    代码

    #include <bits/stdc++.h>
    #define emplace_back push_back
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int N = 2e6 + 10;
    
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            ll a,b,n,m;
            scanf("%lld%lld%lld%lld",&a,&b,&n,&m);
            if(min(a,b)<m||a+b<n+m) printf("No
    ");
            else printf("Yes
    ");
        }
        // system("pause");
        return 0;
    }
    

    D.

    题意

    给出整数 n , k,让构造出一个 n * n的 01 矩阵,满足一下条件:

    1. 矩阵中 1 的个数为 k 。
    2. 矩阵中 1 的个数 最多的行 和 最少的行 的差值的平方+ 最多的列 和 最少的列 的差值的平方

    思路

    直接把行和列分开来看。

    当 n == 4 的时候,行的分配:

    1 2 3 4 1 2 3 4 1 2 3 4...

    列的分配:

    1 2 3 4 2 3 4 1 3 4 1 2 ....

    一一对应组合

    (1,1)(2,2)(3,3)(4,4)(1,2)....

    选择 k 个即可。

    代码

    #include <bits/stdc++.h>
    #define emplace_back push_back
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int N = 1e6 + 10;
    
    int x[N],y[N],vis[310][310],r[310],c[310];
    
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            memset(r,0,sizeof(r));
            memset(c,0,sizeof(c));
            memset(vis,0,sizeof(vis));
            int n,k;
            scanf("%d%d",&n,&k);
            for(int i=1;i<=n*n;i++) x[i]=(i-1)%n+1;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    y[(i-1)*n+j]=(i+j-2)%n+1;
                }
            }
            for(int i=1;i<=k;i++){
                vis[x[i]][y[i]]=1;
                r[x[i]]++,c[y[i]]++;
            }
            int ans=0;
            int minn=inf,maxn=-1;
            for(int i=1;i<=n;i++){
                minn=min(minn,r[i]);
                maxn=max(maxn,r[i]);
            }
            ans+=(maxn-minn)*(maxn-minn);
            minn=inf,maxn=-1;
            for(int i=1;i<=n;i++){
                minn=min(minn,c[i]);
                maxn=max(maxn,c[i]);
            }
            ans+=(maxn-minn)*(maxn-minn);
            printf("%d
    ",ans);
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    printf("%d",vis[i][j]);
                }
                printf("
    ");
            }
        }
        return 0;
    }
    

    E2.

    题意

    小明有 x 个糖果,有 n 个敌人,第 i 个敌人有 (a_i) 颗糖果,小明现在要和敌人通过糖果战斗。

    规则为:如果小明的糖果数量大于等于当前敌人的糖果数量,那么小明胜利,赢得一个糖果。

    小明可以生成一个 n 的全排列,然后将敌人按照此排列一次战斗。

    现在给出 n 个敌人拥有的糖果数量,并给定一个小于等于 n 的素数 p ,问 x 的值可以是多少,当 小明有 x 个糖果的时候,假设有 (f(x)) 种排列方式使得小明可以赢过所有敌人,统计 (f(x)\%p !=0)的 x 的个数。

    思路

    这题我是抱着莽的心态过掉的。。。

    首先大致确定 x 的取值范围,(x >= min(a_i)) ,另外小明胜利一次只会获得一次糖果,所以 x >= (max(a_i)-n+1)

    然后再看当 x 的值确定的时候,全排列的方式有几种?

    当 x 的值确定了,那么和第 i 个人战斗时的糖果数量也就确定了:

    x x+1 x+2 x+3 x+4 x+5 ... x+n-1

    那么对于 a 数组的全排列要使得第 i 个值,小于等于 (x+i)

    首先将 a 数组按照升序排序。

    对于(a_i) 它可以放的第一个位置为 (a_i-x+1_{最小取1}) ,可以放的位置有(g(a_i)) =(i-(a_i-x+1)+1= x-a_i+i)个。

    对于每个 i 都求一遍,就我找的几个样例来说,(g(a_i))相乘就是答案。因为 %的是一个质数 p ,所以只需要判断是否存在

    (g(a_i)) >=p 即可。

    可以看出 x 越大,(g(a_i))越大,那么应该存在一个分界线,当 x < 分界线的时候可以,否则不可以。

    二分检验一下,找到这个分界线,wa了。。。

    然后看错误样例发现好像开始的一部分也存在不合法的,所以在求完结尾之后,再二分一个开头。
    就过了

    代码

    #include <bits/stdc++.h>
    #define emplace_back push_back
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int N = 1e6 + 10;
    
    int arr[N],p,n;
    int check(int x){
        for(int i=n;i;i--){
            int pre=arr[i]-x+1;
            if(pre<=0) pre=1;
            if((i-pre+1)%p==0) return 0;
        }
        return 1;
    }
    int main()
    {
        scanf("%d%d",&n,&p);
        int maxn=-1,minn=inf;
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&arr[i]);
            maxn=max(maxn,arr[i]);
            minn=min(minn,arr[i]);
        }
        sort(arr+1,arr+1+n);
        int l=max(minn,maxn-n+1),r=maxn-1;
        int en=-1;
        while(l<=r){
            int mid=(l+r)/2;
            if(check(mid)){
                en=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        int aga=-1;
        l=max(minn,maxn-n+1),r=en;
        while(l<=r){
            int mid=(l+r)/2;
            if(check(mid)){
                aga=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        if(en==-1){
            printf("0
    ");
            return 0;
        }
        printf("%d
    ",en-aga+1);
        for(int i=aga;i<=en;i++){
            printf("%d ",i);
        }
        printf("
    ");
        return 0;
    }
    
  • 相关阅读:
    《Programming in Lua 3》读书笔记(十)
    《Programming in Lua 3》读书笔记(九)
    《Programming in Lua 3》读书笔记(八)
    [原]NYOJ-括号匹配-2(java)
    [原]NYOJ-字符串替换-113
    [原]NYOJ-小光棍数-458
    [原]NYOJ-公约数和公倍数 -40
    [原]NYOJ-开灯问题-77
    [原]NYOJ-数的位数-69
    [原]NYOJ-大数阶乘-28
  • 原文地址:https://www.cnblogs.com/valk3/p/13361987.html
Copyright © 2011-2022 走看看