壁打ちAtCoder

AtCoderの問題をひたすら解いてくブログです。思考やコードの書き方の私的備忘録として

AtCoder Beginner Contest 062 by C

AtCoder Beginner Contest 062 について
C言語での回答

atcoder.jp

できたもの
A
B

できなかったもの
C
D

問題A

#include <stdio.h>

int main(void){
    int x,y,i,j;
    scanf("%d %d", &x,&y);

    if(x==2||y==2){
        printf("No");
        return 0;
    }
    else if(x==1||x==3||x==5||x==7||x==8||x==10||x==12){
        if(y==1||y==3||y==5||y==7||y==8||y==10||y==12){
            printf("Yes");
            return 0;
        }
        printf("No");
        return 0;
    }
    else if(x==4||x==6||x==9||x==11){
        if(y==4||y==6||y==9||y==11){
            printf("Yes");
            return 0;
        }
            printf("No");
            return 0;
    }

    
    return 0;
}

最初配列に値を入れて、それで参照して~とかやってましたが、数も少ないので論理和直書きで。

問題B

#include <stdio.h>

int main(void){
    int h,w,i,j;
    char a[101][101];
    scanf("%d %d", &h,&w);

    for(i=0;i<h;i++){
        scanf("%s", a[i]);
    }


    for(i=0;i<w+2;i++){
        printf("#");
    }
    printf("\n");
    for(i=0;i<h;i++){
        printf("#");
        for(j=0;j<w;j++){
            printf("%c", a[i][j]);
        }
        printf("#\n");
    }
    for(i=0;i<w+2;i++){
        printf("#");
    }
    
    return 0;
}

受け取った画像(文字列)の周り1ピクセルを#で囲います。
元の文字列については前後に#を付けます(abc → #abc#)
ループの前と後に#だけの行を出力すれば無事囲えます。

問題C

#include <stdio.h>

const long long inf = (long long)1 << 60;

long long H,W;

long long max(long long a,long long b){
    return a > b ? a : b;
}

long long min(long long a,long long b){
    return a > b ? b : a;
}

long long f(long long a, long long b, long long c){
    long long ma = max(a,max(b,c));
    long long mi = min(a,min(b,c));
    return ma - mi;
}

long long solA(){
    long long res = inf;
    if(2<H){
        long long h = H/3;
        if(H%3==0){
            return 0;
        }
        res = min(res,W);
    }

    if(2<W){
        if(W%3==0){
            return 0;
        }
        res = min(res,H);
    }
    return res;
}

long long solB(){
    long long res = inf;
    int i,j;
    for(i=1;i<W;i++){
        long long xx = i;
        long long b = H/2;
        res = min(res, f(xx*b,xx*(H-b),(W-xx)*H));
    }
    for(j=1;j<H;j++){
        long long yy = j;
        long long b = W/2;
        res = min(res, f(yy*b,yy*(W-b),(H-yy)*W));
    }
    return res;
}

int main(void){
    scanf("%lld %lld", &H,&W);
    long long ans = min(solA(),solB());
    printf("%lld\n", ans);
    return 0;
}

f:id:Rgrayjourney:20210531210054j:plain
3等分する方法は上の4通り(解説を元にプログラムに合わせて書きました)
関数solAでは上2つのやり方で分けた時に差が小さい方の値を、関数solBでは下2つのやり方で分けた時に差が小さい方を返します。
メイン関数でその返り値を比較し、小さい方が4通りの中で最も小さくなる値です。
C言語にはSTL関数がないのでプログラムの先頭に自分で作ってます。

解けなかった原因

方針が思い付かなかった。

問題D