zoukankan      html  css  js  c++  java
  • Codeforces Round #654 (Div. 2)A-E1

    题目链接:https://codeforces.com/contest/1371

    题目说明:

    A.Magical Sticks(简单思维)

    B.Magical Calendar(思维)

    C.Cookie for you(简单思维)

    D.Grid-00100(规律构造)

    E1.Asterism(Easy Version)--暴力

    E2.Asterism(Hard Version)--无能为力

    F.Raging Thunder(无能为力)

    A.Magical Sticks(简单思维)

    题目大意:给你n根木棍,长度为1到n,你可以将任意两根棍子拼接形成一根新的棍子,问,最多能够使得多少根木棍的长度一样。

    Example
    input
    4
    1
    2
    3
    4
    
    output
    1
    1
    2
    2

    。。。手动写几个数据就知道了,全部都是向最大的数靠拢,那么答案很明显了,我们给个奇数和偶数看看就知道了:

    1 2 3 4->1-3,4共2个

    1 2 3 4 5->1-4,2-3,5共3个

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int t,n;
        scanf ("%d",&t);
        while (t--){
            scanf ("%d",&n);
            int ans=(n+1)/2;
            printf("%d
    ",ans);
        }
    
        return 0;
    }
    View Code

    B.Magical Calendar(思维)

    题目大意:规定每周的天数为1~R中的任意一个数。现在要选择连续的N天,在日历上将这N天涂上颜色。问对于1~R不同的天数,总共有多少种不一样的形状。

    Example
    input
    5
    3 4
    3 2
    3 1
    13 7
    1010000 9999999
    
    output
    4
    3
    1
    28
    510049495001

    实际上每周的天数决定的是表格的宽度,而表格的长度是无限的。对于天数小于每周天数的情况,那么只能涂在同一行了,总的个数就是1。对于大于每周天数的情况,第一周的选择可以是只涂最后一格、只涂最后两格.....涂满整周,每种涂法形状都不同,因此答案就是每周的天数r。那么从1到r,我们只需分类讨论一下就完事了

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    int main()
    {
        int t;
        int n,r;
        scanf ("%d",&t);
        while (t--){
            scanf ("%d%d",&n,&r);
            if (n>r) {
                ll ans=(1LL+r)*r/2;
                printf("%lld
    ",ans);
            }
            else {
                ll ans=(1LL+n-1)*(n-1)/2+1;
                printf("%lld
    ",ans);
            }
        }
    
        return 0;
    }
    View Code

    C.Cookie for you(简单思维)

    题目大意:有a个vanilla cookies和b个chocolate cookies,现在要邀请n个性格属性为1的客人和m个性格属性为2的客人。性格属性为1的客人吃cookie的习惯是:如果 a > b 则吃一个vanilla cookie,否则吃一个chocolate cookie。性格属性为2的客人的习惯与属性1的相反。现在给定a、b、n、m,问能否安排客人前来聚会的顺序,使得每一个人都有cookie吃。

    Example
    input
    6
    2 2 1 2
    0 100 0 1
    12 13 25 1
    27 83 14 25
    0 0 1 0
    1000000000000000000 1000000000000000000 1000000000000000000 1000000000000000000
    
    output
    Yes
    No
    No
    Yes
    No
    Yes

    值得注意的是他并不是一个一个地邀请,而是一类人一类人地邀请。。。然后就很简单了,最优的决策肯定是先邀请吃少的那部分人。那么答案也就出来了了

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    int main()
    {
        int t;
        scanf ("%d",&t);
        while (t--){
            ll a,b,n,m;
            scanf ("%lld%lld%lld%lld",&a,&b,&n,&m);
            if (a+b<n+m) {printf("No
    "); continue;}
            if (min(a,b)<m) {printf("No
    "); continue;}
            printf("Yes
    ");
        }
    
        return 0;    
    }
    View Code

    D.Grid-00100(规律构造)

    题目大意:给你一个n*n的01矩阵,其中1的个数为k,定义矩阵A的一个属性$F(A),R_i,C_i$,其中$R_i$ 为01矩阵第 $i$ 行中 1 的数量。$C_i$ 为01矩阵第 $i$ 列中 1 的数量 。其中$F(A)=(Max(R)-Min(R))^2+(Max(C)-Min(C))^2$,要使得$F(A)$值最小,请你构造这样的01矩阵,并输出$F(A)$值

    Example
    input
    4
    2 2
    3 8
    1 0
    4 16
    
    output
    0
    10
    01
    2
    111
    111
    101
    0
    0
    0
    1111
    1111
    1111
    1111

    通过第一个样例我们就应该察觉到对角线优先放置是最优的,那么我们可以先对n*n的表格标号放置的顺序如下所示:

    int flag=0,nb=1,line1=2,line2=1,zu=1;
    for (int i=1; i<=n; i++) id[i][i]=nb++,mp[nb-1]=node {i,i};
    while (nb<=n*n) {
        if (!flag) {
            for (int i=line1; i<=n; i++) {
                int j=i-zu;
                id[i][j]=nb++;
                mp[nb-1]=node {i,j};
            }
            flag^=1;
            line1++;
        } 
        else {
            for (int i=line2; i<=zu; i++) {
                int j=i+(n-zu);
                id[i][j]=nb++;
                mp[nb-1]=node {i,j};
            }
            flag^=1;
            zu++;
        }
    }

    得到的id结果为:

    1  14   11  8
    5   2    15 12
    9   6    3   16
    13 10  7    4

    然后按照这个顺序进行填充1就好了。

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int mac=310;
    const int inf=1e8;
    
    int a[mac][mac],id[mac][mac];
    struct node
    {
        int x,y;
    }mp[mac*mac];
    
    int qpow(int x) {return x*x;}
    
    int main()
    {
        int t,n,m;
        scanf ("%d",&t);
        while (t--){
            scanf ("%d%d",&n,&m);
            memset(a,0,sizeof a);
            memset(id,0,sizeof id);
            int flag=0,nb=1,line1=2,line2=1,zu=1;
            for (int i=1; i<=n; i++) id[i][i]=nb++,mp[nb-1]=node{i,i};
            while (nb<=n*n){
                if (!flag){
                    for (int i=line1; i<=n; i++){
                        int j=i-zu;
                        id[i][j]=nb++;
                        mp[nb-1]=node{i,j};
                    }
                    flag^=1;
                    line1++;
                }
                else {
                    for (int i=line2; i<=zu; i++){
                        int j=i+(n-zu);
                        id[i][j]=nb++;
                        mp[nb-1]=node{i,j};
                    }
                    flag^=1;
                    zu++;
                }
            }
    
            for (int i=1; i<=m; i++){
                int x=mp[i].x,y=mp[i].y;
                a[x][y]=1;
            }
    
            int min_r=inf,min_c=inf,max_c=0,max_r=0;
            for (int i=1; i<=n; i++) {
                int r=0,c=0;
                for (int j=1; j<=n; j++) r+=a[i][j],c+=a[j][i];
                min_r=min(min_r,r);max_r=max(max_r,r);
                min_c=min(min_c,c);max_c=max(max_c,c);
            }
            printf ("%d
    ",qpow(max_c-min_c)+qpow(max_r-min_r));
            for (int i=1; i<=n; i++){
                for (int j=1; j<=n; j++)
                    printf("%d",a[i][j]);
                printf("
    ");
            }
        }
        return 0;
    }
    View Code

    E1.Asterism(Easy Version)--暴力

    题目大意:你有n个敌人,每个敌人手中有a[i]个糖果,你初始的时候有x个糖果,现在你要和敌人对战,你可以决定敌人的排列顺序,其决战的规则为:你手中的糖果大于等于敌人的,则获胜,且额外获得一颗糖果。你要战胜所有的敌人。定义$f(x)$为当初始有$x$个糖果时有$f(x)$中排列使得你全胜,当$f(x)modp=0$ 这个答案是不够优秀的,反之则是优秀的,问你有多少个优秀的答案,并将其输出。

    Examples
    input
    3 2
    3 4 5
    
    output
    1
    3
    
    input
    4 3
    2 3 5 6
    
    output
    2
    3 4

    设置mx为敌人手中最大的糖果数,那么可以知道的是x的最小值为mx-n+1,最大值为mx-1。因为,大于等于最大值的时候无论怎么放都是OK的,那么方法有N!中,但p<N,所以N!%p=0。我们枚举x,判断x是否合法,判断函数如下:

    int ok(int x,int p,int mx)
    {
        int ans=1,v=0;
        for (int i=1; i<=n; i++) 
            if (a[i]<x) v++;
        for (int i=x; i<=x+n-1; i++){
            if (i<=mx) v+=num[i];
            ans=ans*v%p;
            v--;
        }
        return ans!=0;
    }

    第i个位置有v种情况,那么我直接将答案乘以他就好了,然后拿走一种情况。

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int mac=2e3+10;
    
    int a[mac],num[mac],n;
    
    int ok(int x,int p,int mx)
    {
        int ans=1,v=0;
        for (int i=1; i<=n; i++) 
            if (a[i]<x) v++;
        for (int i=x; i<=x+n-1; i++){
            if (i<=mx) v+=num[i];
            ans=ans*v%p;
            v--;
        }
        return ans!=0;
    }
    
    int main()
    {
        int p,mx=0;
        scanf ("%d%d",&n,&p);
        for (int i=1; i<=n; i++)
            scanf ("%d",&a[i]),num[a[i]]++,mx=max(mx,a[i]);
        int flag=0,x;
        vector<int>ans;
        for (int i=mx-n+1; i<mx; i++){
            if (i<=0) i=1;
            if (ok(i,p,mx)) ans.push_back(i);
        }
        printf("%d
    ",ans.size());
        for (auto x:ans)
            printf("%d ",x);
        printf("
    ");
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    多线程02
    多线程01
    CSS
    Mybatis CRUD中万能Map的用法及优势
    Tomcat配置
    Node.js+Vue+Webpack
    Java的几种常见排序算法
    maven插件 mybatis逆向工程
    ssm依赖
    mybatis spring整合依赖配置
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13231248.html
Copyright © 2011-2022 走看看