2025年1月13日月曜日

その他のA問題(ABC221-235)


四捨五入

ABC226-A

問題概要

与えられた実数(小数第三位まで表示)を小数第一位で四捨五入し、整数として出力せよ。

解答

f=gets.chomp.to_f
puts f.round
    

上がコンテスト中に提出したコード。(2021-11-07 21:16:08)

Cで書いたのが以下。(2024-10-25 22:35:03)

#include<stdio.h>
#include<stdlib.h>
#define N1 9
int main(void){
    char* s=(char*)malloc(sizeof(char)*N1);
    if (s==NULL){
        printf("memory allocation to s failed.\n");
        exit(1);
    }
    char *ts=fgets(s,N1,stdin);
    if(ts==NULL){
        printf("fgets(s) failed\n");
        exit(1);
    }
    int ans=0,i=0;
    while(*(s+i)>=48 && *(s+1)<=57){
        ans*=10;
        ans+=*(s+i)-48;
        i++;
    }
    if(*(s+i)!=46){
        printf("%d\n",ans);
        exit(0);
    }
    i++;
    if(*(s+i)>52)ans+=1;
    printf("%d\n",ans);
    return 0;
}
    

単純計算

ABC231-A

問題概要

与えられた整数を1/100倍して出力せよ。

解答

d=gets.chomp.to_f
puts d/100    
    

上がコンテスト中に提出したコード。(2021-12-11 21:03:03)

Cで書いたのが以下。(2024-11-13 23:03:33)

#include<stdio.h>
#include<stdlib.h>
#define N1 7
int readint(char *s);
int main(void){
    char* s=(char*)malloc(sizeof(char)*N1);
    if (s==NULL){
        printf("memory allocation to s failed.\n");
        exit(1);
    }
    char *ts=fgets(s,N1,stdin);
    if(ts==NULL){
        printf("fgets(s) failed\n");
        exit(1);
    }
    int d=readint(s);
    printf("%f\n",(double)d/100);
    return 0;
}
int readint(char *s){
    int i=0,ret=0;
    while(*(s+i)>=48 && *(s+i)<=57){
        ret*=10;
        ret+=*(s+i)-48;
        i+=1;
    }
    return ret;
}
    

単純計算

ABC232-A

問題概要

a,bを1以上9以下の整数とし、axbという文字列が与えられる。a*bを計算して出力せよ。

解答

a=gets.chars
puts a[0].to_i * a[2].to_i    
    

上がコンテスト中に提出したコード。(2021-12-19 21:16:37)

Cで書いたのが以下。(2024-11-20 22:24:53)

#include<stdio.h>
#include<stdlib.h>
#define N1 5
int main(void){
    char* s=(char*)malloc(sizeof(char)*N1);
    if (s==NULL){
        printf("memory allocation to s failed.\n");
        exit(1);
    }
    char *ts=fgets(s,N1,stdin);
    if(ts==NULL){
        printf("fgets(s) failed\n");
        exit(1);
    }
    int ans=(*s-48)*(*(s+2)-48);
    printf("%d\n",ans);
    return 0;
}
    

ABC233-A

問題概要

aをb以上にするためには、aに10を最小で何回加算する必要があるか。

解答

a,b=gets.split.map(&:to_i)
i=0
while a+10*i < b do
    i+=1
end
puts i    

上がコンテスト中に提出したコード。(2021-12-25 21:47:22)

Cで書いたのが以下。(2024-11-20 22:50:44)

#include<stdio.h>
#include<stdlib.h>
#define N1 11
int readint(char *s);
int main(void){
    char* s=(char*)malloc(sizeof(char)*N1);
    if (s==NULL){
        printf("memory allocation to s failed.\n");
        exit(1);
    }
    char *ts=fgets(s,N1,stdin);
    if(ts==NULL){
        printf("fgets(s) failed\n");
        exit(1);
    }
    int x=readint(s);
    int i=0;
    while(*(s+i)!=32)i++;
    i++;
    int y=readint(s+i);
    int ans=0;
    if(x<y){
        int d=y-x;
        if(d%10==0)ans=d/10;
        else ans=(d/10)+1;
    }
    printf("%d\n",ans);
    return 0;
}
int readint(char *s){
    int i=0,ret=0;
    while(*(s+i)>=48 && *(s+i)<=57){
        ret*=10;
        ret+=*(s+i)-48;
        i+=1;
    }
    return ret;
}
    

今回cで書いたコードは、まずbとaの差を求め、それを10で割った商を答えとするというのを基本とするが、その際、差を10で割ったときに余りが出るかどうかで場合分けが必要なのが要注意である。一方、以前にRubyで書いたときのやり方は、aが10未満である限りaに10を足すことを繰り返してその回数を数えるというもので、bとaの差が大きいときには計算回数が多くなってしまうという難点はあるものの、場合分けは必要ない。


ABC234-A

問題概要

関数 f を f(x)=x^2+2x+3 と定義します。整数 t が入力されるので、 f(f(f(t)+t)+f(f(t))) を求めてください。

解答

def f(x)
    x*x+2*x+3
end
t=gets.to_i

puts f(f(f(t)+t)+f(f(t)))
    

上がコンテスト中に提出したコード。(2022-01-08 21:07:34)

Cで書いたのが以下。(2024-11-25 22:39:10)

#include<stdio.h>
#include<stdlib.h>
#define N1 4
int readint(char *s);
int f(int x);
int main(void){
    char* s=(char*)malloc(sizeof(char)*N1);
    if (s==NULL){
        printf("memory allocation to s failed.\n");
        exit(1);
    }
    char *ts=fgets(s,N1,stdin);
    if(ts==NULL){
        printf("fgets(s) failed\n");
        exit(1);
    }
    int t=readint(s);
    printf("%d\n",f(f(f(t)+t)+f(f(t))));
    return 0;
}
int readint(char *s){
    int i=0,ret=0;
    while(*(s+i)>=48 && *(s+i)<=57){
        ret*=10;
        ret+=*(s+i)-48;
        i+=1;
    }
    return ret;
}
int f(int x){
    return x*x+2*x+3;
}
    

計算の工夫

ABC235-A

問題概要

3 つの数字 x,y,z をこの順に並べてできる 3 桁の整数を xyz と表すことにします。どの桁も 0 でない 3 桁の整数 abc が与えられるので、abc+bca+cab を求めてください。

解答

s=gets.chomp.split("")
a,b,c=s[0],s[1],s[2]
puts (a+b+c).to_i+(b+c+a).to_i+(c+a+b).to_i    

上がコンテスト中に提出したコード。(2022-01-15 21:06:13)

Cで書いたのが以下。(2024-11-27 22:19:15)

#include<stdio.h>
#include<stdlib.h>
#define N1 5
int main(void){
    char* s=(char*)malloc(sizeof(char)*N1);
    if (s==NULL){
        printf("memory allocation to s failed.\n");
        exit(1);
    }
    char *ts=fgets(s,N1,stdin);
    if(ts==NULL){
        printf("fgets(s) failed\n");
        exit(1);
    }
    int a=*s-48;
    int b=*(s+1)-48;
    int c=*(s+2)-48;
    printf("%d\n",(a+b+c)*111);
    return 0;
}
    

中学受験算数でもよく見かける気のするタイプの問題である。勿論、馬鹿正直に3つの数を足してもよいのだが、(100a+10b+c)+(100b+10c+a)+(100c+10a+b)=100(a+b+c)+10(a+b+c)+(a+b+c)=111(a+b+c)であることに気づけば、最後の掛け算の筆算はabcを一つずつずらして書いて足せばいいだけなので楽にできる。コンピュータを使う場合にはその方法を使う意味はそれほどないが、やはり何の工夫もないコードを書くよりはいいだろうと思って書いたのが上のコード。

一方、敢えて問題文の通りに文字を入れ替えたものを整数として読み込んで足すという方法もある。コードとしてはこちらの方が面白いかもしれない。それで書いたのが以下。(2024-11-27 22:26:06)前にRubyで書いたときも同じようなやり方をしていた。

#include<stdio.h>
#include<stdlib.h>
#define N1 5
int readint(char *s);
int main(void){
    char* s=(char*)malloc(sizeof(char)*N1);
    if (s==NULL){
        printf("memory allocation to s failed.\n");
        exit(1);
    }
    char *ts=fgets(s,N1,stdin);
    if(ts==NULL){
        printf("fgets(s) failed\n");
        exit(1);
    }
    int x1=readint(s);
    char t=*s;
    *s=*(s+1);
    *(s+1)=*(s+2);
    *(s+2)=t;
    int x2=readint(s);
    t=*s;
    *s=*(s+1);
    *(s+1)=*(s+2);
    *(s+2)=t;
    int x3=readint(s);
    printf("%d\n",x1+x2+x3);
    return 0;
}
int readint(char *s){
    int i=0,ret=0;
    while(*(s+i)>=48 && *(s+i)<=57){
        ret*=10;
        ret+=*(s+i)-48;
        i+=1;
    }
    return ret;
}