码迷,mamicode.com
首页 > 其他好文 > 详细

【日记】12.28/【题解】AtCoder AGC041

时间:2019-12-31 14:21:04      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:ini   efi   define   N个问题   main   char s   sort   存在   space   

12.28

这一天补了上次两道CF上的题目,之后写了一堆dp模板,最后打了一把AtCoder,感觉相当不错,不过也是构造题比较玄学才能过吧。

A.Table Tennis Training

题意:有2n个运动员,n张桌子。在x桌子上,赢的人会进入x-1,输的人会进入x+1,除了1和n桌子上的人之外、现在有两个巨强无比的人分别在A和B桌子上,可以随意控制输赢,问他们最少需要用多少轮才能在一张桌子上打。

思路:如果AB本来就相邻,那么必须要把他俩推到一边(1或N)才可以,如果恰好差2,那么可以一赢一输放到中间。因此首先判断差值奇偶性,偶数的话直接/2就行了,如果是奇数,就看谁更靠近边缘,先让他靠边,然后再边上打一轮,把差值变成偶数,之后再靠近。注意开LL。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define mid ((l+r)>>1)
const int M=1e5+20,P=1e9+7;
struct Task{
    LL n,a,b;
    void init(){
        scanf("%lld%lld%lld",&n,&a,&b);
    }
    void run(){
        init();
        if ((a-b)%2==0)
            printf("%lld\n",abs(b-a)/2);
        else
            printf("%lld\n",min(a-1,n-b)+(abs(a-b)+1)/2);
    }
}t;
int main(){
    t.run();
    return 0;
}

B.Voting Judges

题意:有N个问题,一开始每个问题有a[i]分数。有M个裁判,每个人都会恰好选V个问题,这些问题分数+1。最后会选择分数最高的P个问题选出来,如果有分数相同,那么chief会随机排名。现在问有多少个问题有可能被选出来?

思路:显然满足二分性质(当然直接扫一遍也可以)。首先按a[i]从小到大排序,我们来考虑判断第i个问题是否能被选中。投票可以等价为,要添加MV,但每个问题最多增加M,增加之后第i个问题的排名要>=N-P+1。那么可以这样贪心,首先第i的问题肯定尽可能多得票,即获得M,之后再让前P-1的问题每个获得M,即n-p+2到n,再之后,由于第i个问题增加了M,那么1到i-1这些问题也可以获得M,反正加了之后又不会超过第i个问题。这样就已经分出去了(1+P-1+i-1)*M个选票。之后还剩下i+1-n-p这些问题(以k表示),他们也可以获得选票,但获得的选票最多不超过(a[i]+M-a[k]),这样保证在最后排名的时候,中间的问题不会超过第i个问题,这样第i个问题就至少排在第p位。中间那个可以用前缀和来处理。可以二分找分界点,也可以直接On扫。反正判断都是O(1)的。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define mid ((l+r)>>1)
const int M=3e5+20,P=1e9+7;
struct Task{
    LL n,m,v,p,a[M];
    LL sum[M];
    void init(){
        scanf("%lld%lld%lld%lld",&n,&m,&v,&p);
        for(int i=1;i<=n;++i)
            scanf("%lld",&a[i]);
    }
    void run(){
        init();
        sort(a+1,a+n+1);
        for(int i=1;i<=n;++i)
            sum[i]=sum[i-1]+a[i];
        LL ans=n-p;
        while(ans>=1){
            if(a[ans]+m<a[n-p+1])
                break;
            if(1LL*(ans+p-1)*m+1LL*(n-p+1-(ans+1)+1)*(a[ans]+m)-(sum[n-p+1]-sum[ans])>=1LL*v*m)
                --ans;
            else
                break;
        }
        printf("%lld\n",n-ans);
    }
}t;
int main(){
    t.run();
    return 0;
}

C.Domino Quality

题意:有一堆1*2的方块,可以横放或竖放在n×n的网格中。要求摆上去之后,每个横行和竖列出现的方块数相同。

思路:构造题。2不存在,34567都可以搞出来,3是横竖都是2,4567横竖都是3。那么接下来用这些就可以来做了对6k+3,直接用3去拼。

对6k,6k+4,6k+5,首先拼k个6×6,之后再添加一个4×4或5×5.

对6k+1,6k+2,首先拼k-1个6×6,之后再添加一个7×7或两个4×4即可。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define mid ((l+r)>>1)
const int M=1e3+20,P=1e9+7;
struct Task{
    int n;
    char s[M][M];
    void init(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                s[i][j]='.';
    }
    void run(){
        init();
        if (n==2){
            cout<<-1<<endl;
            return ;
        }
        if (n%3==0){
            for(int i=1;i<=n/3;++i){
                int ca=3*(i-1);
                s[ca+1][ca+1]=s[ca+1][ca+2]='a';
                s[ca+1][ca+3]=s[ca+2][ca+3]='b';
                s[ca+2][ca+1]=s[ca+3][ca+1]='c';
                s[ca+3][ca+2]=s[ca+3][ca+3]='d';
            }
            for(int i=1;i<=n;++i){
                for(int j=1;j<=n;++j)
                    putchar(s[i][j]);
                putchar('\n');
            }
            return;
        }
        if (n%6==0||n%6==4||n%6==5){
            for(int i=1;i<=n/6;++i){
                int ca=6*(i-1);
                s[ca+1][ca+1]=s[ca+2][ca+1]='a';
                s[ca+1][ca+4]=s[ca+2][ca+4]='b';
                s[ca+1][ca+5]=s[ca+1][ca+6]='c';
                s[ca+2][ca+5]=s[ca+2][ca+6]='d';
                s[ca+3][ca+2]=s[ca+4][ca+2]='e';
                s[ca+3][ca+3]=s[ca+3][ca+4]='f';
                s[ca+3][ca+5]=s[ca+4][ca+5]='g';
                s[ca+4][ca+3]=s[ca+4][ca+4]='h';
                s[ca+5][ca+1]=s[ca+5][ca+2]='i';
                s[ca+6][ca+1]=s[ca+6][ca+2]='j';
                s[ca+5][ca+3]=s[ca+6][ca+3]='k';
                s[ca+5][ca+6]=s[ca+6][ca+6]='l';
            }
            int ca=6*(n/6);
            if (n%6==4){
                s[ca+1][ca+1]=s[ca+1][ca+2]='a';
                s[ca+2][ca+1]=s[ca+2][ca+2]='b';
                s[ca+1][ca+3]=s[ca+2][ca+3]='c';
                s[ca+1][ca+4]=s[ca+2][ca+4]='d';
                s[ca+3][ca+1]=s[ca+4][ca+1]='e';
                s[ca+3][ca+2]=s[ca+4][ca+2]='f';
                s[ca+3][ca+3]=s[ca+3][ca+4]='g';
                s[ca+4][ca+3]=s[ca+4][ca+4]='h';
            }
            if (n%6==5){
                s[ca+1][ca+1]=s[ca+2][ca+1]='a';
                s[ca+3][ca+1]=s[ca+4][ca+1]='b';
                s[ca+5][ca+1]=s[ca+5][ca+2]='c';
                s[ca+5][ca+3]=s[ca+5][ca+4]='d';
                s[ca+5][ca+5]=s[ca+4][ca+5]='e';
                s[ca+3][ca+5]=s[ca+2][ca+5]='f';
                s[ca+1][ca+5]=s[ca+1][ca+4]='g';
                s[ca+1][ca+3]=s[ca+1][ca+2]='h';
                s[ca+2][ca+2]=s[ca+2][ca+3]='i';
                s[ca+3][ca+4]=s[ca+4][ca+4]='j';
            }
            for(int i=1;i<=n;++i){
                for(int j=1;j<=n;++j)
                    putchar(s[i][j]);
                putchar('\n');
            }
            return;
        }
        if (n%6==1||n%6==2){
            for(int i=1;i<=n/6-1;++i){
                int ca=6*(i-1);
                s[ca+1][ca+1]=s[ca+2][ca+1]='a';
                s[ca+1][ca+4]=s[ca+2][ca+4]='b';
                s[ca+1][ca+5]=s[ca+1][ca+6]='c';
                s[ca+2][ca+5]=s[ca+2][ca+6]='d';
                s[ca+3][ca+2]=s[ca+4][ca+2]='e';
                s[ca+3][ca+3]=s[ca+3][ca+4]='f';
                s[ca+3][ca+5]=s[ca+4][ca+5]='g';
                s[ca+4][ca+3]=s[ca+4][ca+4]='h';
                s[ca+5][ca+1]=s[ca+5][ca+2]='i';
                s[ca+6][ca+1]=s[ca+6][ca+2]='j';
                s[ca+5][ca+3]=s[ca+6][ca+3]='k';
                s[ca+5][ca+6]=s[ca+6][ca+6]='l';
            }
            int ca=6*(n/6-1);
            if (n%6==1){
                s[ca+1][ca+1]=s[ca+1][ca+2]='a';
                s[ca+1][ca+3]=s[ca+1][ca+4]='b';
                s[ca+1][ca+6]=s[ca+2][ca+6]='c';
                s[ca+2][ca+1]=s[ca+3][ca+1]='d';
                s[ca+4][ca+1]=s[ca+5][ca+1]='e';
                s[ca+2][ca+2]=s[ca+2][ca+3]='f';
                s[ca+3][ca+3]=s[ca+3][ca+4]='g';
                s[ca+4][ca+5]=s[ca+5][ca+5]='h';
                s[ca+6][ca+5]=s[ca+6][ca+6]='i';
                s[ca+6][ca+2]=s[ca+7][ca+2]='j';
                s[ca+7][ca+4]=s[ca+7][ca+5]='k';
                s[ca+7][ca+6]=s[ca+7][ca+7]='l';
                s[ca+3][ca+7]=s[ca+4][ca+7]='m';
                s[ca+5][ca+7]=s[ca+6][ca+7]='n';
            }
            if (n%6==2){
                s[ca+1][ca+1]=s[ca+1][ca+2]='a';
                s[ca+2][ca+1]=s[ca+2][ca+2]='b';
                s[ca+1][ca+3]=s[ca+2][ca+3]='c';
                s[ca+1][ca+4]=s[ca+2][ca+4]='d';
                s[ca+3][ca+1]=s[ca+4][ca+1]='e';
                s[ca+3][ca+2]=s[ca+4][ca+2]='f';
                s[ca+3][ca+3]=s[ca+3][ca+4]='g';
                s[ca+4][ca+3]=s[ca+4][ca+4]='h';
                ca+=4;
                s[ca+1][ca+1]=s[ca+1][ca+2]='a';
                s[ca+2][ca+1]=s[ca+2][ca+2]='b';
                s[ca+1][ca+3]=s[ca+2][ca+3]='c';
                s[ca+1][ca+4]=s[ca+2][ca+4]='d';
                s[ca+3][ca+1]=s[ca+4][ca+1]='e';
                s[ca+3][ca+2]=s[ca+4][ca+2]='f';
                s[ca+3][ca+3]=s[ca+3][ca+4]='g';
                s[ca+4][ca+3]=s[ca+4][ca+4]='h';
            }
            for(int i=1;i<=n;++i){
                for(int j=1;j<=n;++j)
                    putchar(s[i][j]);
                putchar('\n');
            }
        }
    }
}t;
int main(){
    t.run();
    return 0;
}

D.Problem Scores

回头再补

【日记】12.28/【题解】AtCoder AGC041

标签:ini   efi   define   N个问题   main   char s   sort   存在   space   

原文地址:https://www.cnblogs.com/diorvh/p/12124063.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!