壁打ちAtCoder

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

AtCoder Beginner Contest 069 by C

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

atcoder.jp


できたもの
A
B
C
D

初めて全回答できました!

問題A

#include <stdio.h>

int main(void){
    int n,m;
    scanf("%d %d",&n,&m);

    printf("%d\n", (n-1)*(m-1));
    
    return 0;
}
方針

生まれる街区は線の数-1なので、縦横の数からそれぞれ1を引いてかければ答えです。

問題B

#include <stdio.h>
#include <string.h>

int main(void){
    char s[101];
    scanf("%s", s);
    int size = strlen(s);

    printf("%c", s[0]);
    printf("%d", size-2);
    printf("%c", s[size-1]);
    
    return 0;
}
方針

2文字目からn-1文字目までの文字数が間に表示される数字の数なので、strlenで文字列の長さを取得し、2を引いた数になります。
後は前後に先頭の文字と最後尾の文字を表示すれば解。

問題C

#include <stdio.h>

int main(void){
    int n,i;
    int a[100001];
    scanf("%d", &n);

    int count4 = 0,count2 = 0;
    for(i=0;i<n;i++){
        scanf("%d", &a[i]);
        if(a[i]%4==0){
            count4++;
        }
        if(a[i]%2==0){
            count2++;
        }
    }
    count2 -= count4;

    if(count4>=n/2){
        printf("Yes\n");
    }
    else{
        if(n-(count4*2)==count2){
            printf("Yes\n");
        }
        else{
            printf("No\n");
        }
    }
    
    return 0;
}
方針

4の倍数であれば、隣の数がなんであれ「aiとai+1の積は4の倍数である」という条件を満たせます。
4の倍数を●として条件を満たせる配置の一つとして以下が挙げられます。
奇数:〇●〇●〇
偶数:〇●〇●〇●

つまり、N/2個以上の4の倍数があれば条件を満たせます。

次に4の倍数がN/2未満以下の場合を考えます。
4の倍数でなくても2の倍数同士の積であれば4の倍数になります。
そのため、条件を満たすためには4の倍数と隣合わない数は2の倍数をかけ合わせる必要があります。

〇●〇●〇〇〇
↑の場合には右の3つの積が条件を満たせません。

2の倍数を◎とし、以下の様にならべると条件を満たせます。
〇●〇●◎◎◎

この2の倍数の個数は4の倍数で条件を満たせる数、つまり4の倍数の数×2をNから引いた数と等しければ条件を満たせます。

上のどちらの条件も満たせない場合はNoを出力します。

問題D

#include <stdio.h>

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

    int count1 = 0;
    for(i=0;i<n;i++){
        scanf("%d", &num);
        for(j=0;j<num;j++){
            a[count1] = i+1; 
            count1++;
        }
    }

    int count2 = 0;
    for(i=0;i<h;i++){
        if(i%2==0){
            for(j=0;j<w;j++){
                table[i][j] = a[count2];
                count2++;
            }
        }
        else{
            for(j=w-1;j>=0;j--){
                table[i][j] = a[count2];
                count2++;
            }
        }
    }

    for(i=0;i<h;i++){
        for(j=0;j<w;j++){
            printf("%d ", table[i][j]);
        }
        printf("\n");
    }

    
    return 0;
}
方針

一行に同じ数字を入れていき、列数を越えたら下の行に折り返して後ろから埋める、とジグザグに入れていきます。
例の2を例としてあげると、以下のような配置になります。

12233
44443
55555

解説の図が分かりやすいかと思います。
https://img.atcoder.jp/arc080/editorial.pdf