2022年11月24日木曜日

配列の要素の和

配列の和を求める

ABC272-A

問題概要

配列aが与えられたとき、aの要素の総和を求めよ。

解答

解答1

Arrayクラスにsumメソッドが用意されているので、それを使えばよい。

n=gets.to_i
a=gets.chomp.split(" ").map(&:to_i)
puts a.sum
    

上が本番で提出したコード。

解答2

Arrayクラスのinjectメソッドを使う。

n=gets.to_i
a=gets.chomp.split(" ").map(&:to_i)
puts a.inject {|result, item| result + item }
    

自分で、要素を一個ずつ足す処理を書いていってもいい。

解答3

n=gets.to_i
a=gets.chomp.split(" ").map(&:to_i)
sum=0
a.size.times do |i|
    sum+=a[i]
end
puts sum
    

解答4

n=gets.to_i
a=gets.chomp.split(" ").map(&:to_i)
sum=0
a.each do |item|
    sum+=item
end
puts sum
    

実行時間は、

実行時間(ms)
解答169
解答259
解答359
解答458

となった。

Cでやったのは以下。実行時間は 1 ms。

int isum(int* a, int n);
void input_iarray(char* s,int* a,int n,int imax);
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 20
#define N 100000002
int main(void){
    char* s1=(char*)malloc(sizeof(char)*N1);
    fgets(s1,N1,stdin);
    int n=readint(s1);
    char* s3=(char*)malloc(sizeof(char)*N);
    fgets(s3,N,stdin);
    int * a=(int*)malloc(sizeof(int)*n);
    input_iarray(s3,a,n,N);
    printf("%d\n",isum(a,n));
    return 0;
}
int readint(char *s){
    int i=0,ret=0;
    while(*(s+i)>=48 && *(s+i)<=57){
//        printf("%d\n",*(s+i));
        ret*=10;
        ret+=*(s+i)-48;
        i+=1;
    }
    return ret;
}
void input_iarray(char* s,int* a,int n,int imax){
    int aidx=0,i=0; 
    while(*(s+i)!=0 && i<imax){
        if (*(s+i)<48 || *(s+i)>57){i++;}
        else{
            int bidx=i;
            while(*(s+i)>=48 && *(s+i)<=57){
                i++;
            }
            int t=0;
            for(int j=bidx;j<i;j++){
                t*=10;
                t+=*(s+j)-48;
            }
        *(a+aidx++)=t;
        }
    }
    if (aidx!=n)printf("n!=aidx aidx=%d\n",aidx);
}
int isum(int* a, int n){
    int sum=0;
    for(int i=0;i<n;i++)sum+= *(a+i);
    return sum;
}
    

配列の一部の和(インデックスを指定)

ABC290-A

問題概要

配列aの、b[1]..b[m]番目の和を求めよ。

解答

n,m=gets.chomp.split(" ").map(&:to_i)
a=gets.chomp.split(" ").map(&:to_i)
b=gets.chomp.split(" ").map(&:to_i)
ans=0
b.each do |it|
    ans+=a[it-1]
end
puts ans
    

上が本番で提出したコード。以下はCで書いたもの。

int selected_isum(int* a, int* idxs,int n,int m);
void input_iarray(char* s,int* a,int n,int imax);
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 20
#define N 100000002
int main(void){
    char* s1=(char*)malloc(sizeof(char)*N1);
    fgets(s1,N1,stdin);
    int n=readint(s1);
    int j=0;
    while(*(s1+j)!=32)j++;
    j++;
    int m=readint(s1+j);
//    printf("n=%d m=%d\n",n,m);
    free(s1);
    char* s2=(char*)malloc(sizeof(char)*N);
    fgets(s2,N,stdin);
    int * a=(int*)malloc(sizeof(int)*n);
    input_iarray(s2,a,n,N);
    free(s2);
    char* s3=(char*)malloc(sizeof(char)*N);
    fgets(s3,N,stdin);
    int * b=(int*)malloc(sizeof(int)*m);
    input_iarray(s3,b,m,N);
    free(s3);
    printf("%d\n",selected_isum(a,b,n,m));
    return 0;
}
int readint(char *s){
    int i=0,ret=0;
    while(*(s+i)>=48 && *(s+i)<=57){
//        printf("%d\n",*(s+i));
        ret*=10;
        ret+=*(s+i)-48;
        i+=1;
    }
    return ret;
}
void input_iarray(char* s,int* a,int n,int imax){
    int aidx=0,i=0; 
    while(*(s+i)!=0 && i<imax){
        if (*(s+i)<48 || *(s+i)>57){i++;}
        else{
            int bidx=i;
            while(*(s+i)>=48 && *(s+i)<=57){
                i++;
            }
            int t=0;
            for(int j=bidx;j<i;j++){
                t*=10;
                t+=*(s+j)-48;
            }
        *(a+aidx++)=t;
        }
    }
    if (aidx!=n)printf("n!=aidx aidx=%d\n",aidx);
}
int selected_isum(int* a, int* idxs,int n,int m){
    int sum=0;
    for(int i=0;i<m;i++){
        int idx=*(idxs+i)-1;
        sum+= *(a+idx);
    }
    return sum;
}
    

群ごとの和

ABC307-A

問題概要

与えられた配列を7個ごとの群に区切り、各群の数の和を順に出力せよ。

解答

nn=gets.to_i
a=gets.chomp.split(" ").map(&:to_i)
n=nn*7
r=n%7
if r>0
    b_size=(n/7+1)
else
    b_size=(n/7)
end
b=Array.new(b_size,0)
(n/7).times do |i|
    7.times do |j|
        b[i]+=a[i*7+j]
    end
end
if r>0
    r.times do |j|
        b[i+1]+=a[(n/7)*7+j]
    end
end
puts b.join(" ")
    

最初、nは与えられる配列の要素数だと思って書き進めたのだが、そうではなく、群の数だった。更に、7で割って余りが生じるかどうかの場合分けも不要であった。

上が本番で提出したコード。以下はCで書いたもの。

void print_ivector(int* a,int n);
void input_iarray(char* s,int* a,int n,int imax);
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 20
#define N 100000002
int main(void){
    char* s1=(char*)malloc(sizeof(char)*N1);
    fgets(s1,N1,stdin);
    int n=readint(s1);
    free(s1);
    char* s2=(char*)malloc(sizeof(char)*N);
    fgets(s2,N,stdin);
    int* a=(int*)malloc(sizeof(int)*n*7);
    input_iarray(s2,a,n*7,N);
    free(s2);
    int* weekly=(int*)malloc(sizeof(int)*n);
    for(int i=0;i<n;i++)*(weekly+i)=0;
    int j=0;
    int wn=0;
    while(j<7*n){
        *(weekly+wn)+= *(a+7*wn+j%7);
        if (j%7==6)wn++;
        j++;
    }
    print_ivector(weekly,n);
    return 0;
}
int readint(char *s){
    int i=0,ret=0;
    while(*(s+i)>=48 && *(s+i)<=57){
//        printf("%d\n",*(s+i));
        ret*=10;
        ret+=*(s+i)-48;
        i+=1;
    }
    return ret;
}
void input_iarray(char* s,int* a,int n,int imax){
    int aidx=0,i=0; 
    while(*(s+i)!=0 && i<imax){
        if (*(s+i)<48 || *(s+i)>57){i++;}
        else{
            int bidx=i;
            while(*(s+i)>=48 && *(s+i)<=57){
                i++;
            }
            int t=0;
            for(int j=bidx;j<i;j++){
                t*=10;
                t+=*(s+j)-48;
            }
        *(a+aidx++)=t;
        }
    }
    if (aidx!=n)printf("n!=aidx aidx=%d\n",aidx);
}
void print_ivector(int* a,int n){
    for(int i=0;i<n-1;i++){
        printf("%d ",*(a+i));
    }
    printf("%d\n",*(a+n-1));
}
    

条件を満たす要素の和

ABC328-B

問題概要

整数からなる配列が与えられる。値が一定値以下である要素の和を出力せよ。

解答

n,x=gets.chomp.split(&quot; &quot;).map(&amp;:to_i)
a=gets.chomp.split(&quot; &quot;).map(&amp;:to_i)
ans=0
(0...n).each do |i|
    if a[i]&lt;=x
        ans+=a[i]
    end
end
puts ans
    

上が本番で提出したコード。以下はCで書いたもの。

int if_smaller(int* np,int x);
void input_iarray(char* s,int* a,int n,int imax);
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 20
#define N 100000002
int main(void){
    char* s1=(char*)malloc(sizeof(char)*N1);
    fgets(s1,N1,stdin);
    int n=readint(s1);
    int j=0;
    while(*(s1+j)!=32)j++;
    j++;
    int x=readint(s1+j);
//    printf("n=%d m=%d\n",n,m);
    free(s1);
    char* s2=(char*)malloc(sizeof(char)*N);
    fgets(s2,N,stdin);
    int * a=(int*)malloc(sizeof(int)*n);
    input_iarray(s2,a,n,N);
    free(s2);
    int ans=0;
    for(int i=0;i<n;i++)ans+= (if_smaller(a+i,x));
    printf("%d\n",ans);
    return 0;
}
int readint(char *s){
    int i=0,ret=0;
    while(*(s+i)>=48 && *(s+i)<=57){
//        printf("%d\n",*(s+i));
        ret*=10;
        ret+=*(s+i)-48;
        i+=1;
    }
    return ret;
}
void input_iarray(char* s,int* a,int n,int imax){
    int aidx=0,i=0; 
    while(*(s+i)!=0 && i<imax){
        if (*(s+i)<48 || *(s+i)>57){i++;}
        else{
            int bidx=i;
            while(*(s+i)>=48 && *(s+i)<=57){
                i++;
            }
            int t=0;
            for(int j=bidx;j<i;j++){
                t*=10;
                t+=*(s+j)-48;
            }
        *(a+aidx++)=t;
        }
    }
    if (aidx!=n)printf("n!=aidx aidx=%d\n",aidx);
}
int if_smaller(int* np,int x){
    if (*np<=x)return *np;
    else return 0;
}
    

0 件のコメント:

コメントを投稿