「AOJ再挑戦問15~19」の編集履歴(バックアップ)一覧はこちら

AOJ再挑戦問15~19」(2014/01/11 (土) 08:49:59) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

*問15 National Budget http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0015 80桁までの整数足し算を実装する問題。 解法 多桁計算として実装するのが正しいと思いますが数字を文字列に変換して解きました。 80桁の右詰0埋め文字列に加工して右の桁から左の桁へ足し算をしていきます。 コードが膨らんだのですが賢い方法はあるものでしょうか? #include<stdio.h> #include<string.h> #include<stdlib.h> const int lenLimit=82; void sideRight(char *str,char *result){ int len=strlen(str); memset(result,'0',lenLimit-1); result[lenLimit-1]='\0'; memcpy(result+(lenLimit-len-1),str,len); } void add(char *A,char *B,char *result){ memset(result,'0',lenLimit-1); result[lenLimit-1]='\0'; int add=0,t; for(int i=lenLimit-2;i>=0;i--){ t=A[i]+B[i]+add-2*'0'; result[i]=t%10+'0'; add=t/10; } } void myprint(char *ans){ if(ans[0]!='0'){ printf("overflow\n"); }else{ int p; for(p=0;p<lenLimit-2&&ans[p]=='0';p++); for(;p<lenLimit-1;p++){ printf("%c",ans[p]); } printf("\n"); } } int main(){ int n; scanf("%d",&n); while(n--){ char t1[512],t2[512]; char a[lenLimit],b[lenLimit], sideA[lenLimit],sideB[lenLimit], Ans[lenLimit]; scanf("%s %s",t1,t2); if(strlen(t1)>80 || strlen(t2)>80){ printf("overflow\n"); }else{ sprintf(a,"%s",t1); sprintf(b,"%s",t2); sideRight(a,sideA); sideRight(b,sideB); //printf("%s\n%s\n",sideA,sideB); add(sideA,sideB,Ans); //printf("%s",Ans); myprint(Ans); } } *問16Treasure Hunt http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0016 宝探しを題材にした問題。 **解法 指定通り回転と移動の計算を繰り返すだけです。 三角関数を使えば簡単ですね。 #include<stdio.h> #include<math.h> int main(){ double nowX=0,nowY=0,len; int dr,r=90; while(1){ scanf("%lf,%d",&len,&dr); if(len==0&&dr==0)break; nowX+=len*cos(r/180.0*M_PI); nowY+=len*sin(r/180.0*M_PI); r=r-dr; } printf("%d\n%d\n",(int)nowX,(int)nowY); } *問17 Caesar Cipher http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0017 シーザー暗号を復元する問題。 解法 一行丸ごと読み込んでthisやtheのほうをずらして探します、this,,,という単語を排除するために後ろに空白やピリオドをつけました。。 これも問15と同じくコードが膨らんでる、もうちょっと短くなりそうだけど? #include<stdio.h> #include<string.h> int main(){ char line[82]; while(gets(line)!=NULL){ char words[6][6]={"this ","the ","that ","this.","the.","that."}; int s; for(s=1;s<27;s++){ for(int j=0;j<6;j++){ for(int k=0;k<strlen(words[j])-1;k++){ words[j][k]=(words[j][k]-'a'+1)%26+'a'; } } bool hit=false; for(int j=0;j<6;j++){ if(strstr(line,words[j])!=NULL)hit=true; } if(hit==true)break; } s=26-s; for(int i=0;i<strlen(line);i++){ if(line[i]==' '||line[i]=='.')printf("%c",line[i]); else printf("%c",(line[i]-'a'+s)%26+'a'); } printf("\n"); } } *問18 Sorting Five Numbers http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0018 5つの数字を降順に出力するだけの問題。 解法 std::sortで一発。 #include<stdio.h> #include<algorithm> #include <functional> int main(){ int ns[5]; for(int i=0;i<5;i++)scanf("%d",&ns[i]); std::sort(ns,ns+5,std::greater<int>()); for(int i=0;i<5;i++)printf("%d%c",ns[i],i==4?'\n':' '); }
*問15 National Budget http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0015 80桁までの整数足し算を実装する問題。 解法 多桁計算として実装するのが正しいと思いますが数字を文字列に変換して解きました。 80桁の右詰0埋め文字列に加工して右の桁から左の桁へ足し算をしていきます。 コードが膨らんだのですが賢い方法はあるものでしょうか? #include<stdio.h> #include<string.h> #include<stdlib.h> const int lenLimit=82; void sideRight(char *str,char *result){ int len=strlen(str); memset(result,'0',lenLimit-1); result[lenLimit-1]='\0'; memcpy(result+(lenLimit-len-1),str,len); } void add(char *A,char *B,char *result){ memset(result,'0',lenLimit-1); result[lenLimit-1]='\0'; int add=0,t; for(int i=lenLimit-2;i>=0;i--){ t=A[i]+B[i]+add-2*'0'; result[i]=t%10+'0'; add=t/10; } } void myprint(char *ans){ if(ans[0]!='0'){ printf("overflow\n"); }else{ int p; for(p=0;p<lenLimit-2&&ans[p]=='0';p++); for(;p<lenLimit-1;p++){ printf("%c",ans[p]); } printf("\n"); } } int main(){ int n; scanf("%d",&n); while(n--){ char t1[512],t2[512]; char a[lenLimit],b[lenLimit], sideA[lenLimit],sideB[lenLimit], Ans[lenLimit]; scanf("%s %s",t1,t2); if(strlen(t1)>80 || strlen(t2)>80){ printf("overflow\n"); }else{ sprintf(a,"%s",t1); sprintf(b,"%s",t2); sideRight(a,sideA); sideRight(b,sideB); //printf("%s\n%s\n",sideA,sideB); add(sideA,sideB,Ans); //printf("%s",Ans); myprint(Ans); } } *問16Treasure Hunt http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0016 宝探しを題材にした問題。 **解法 指定通り回転と移動の計算を繰り返すだけです。 三角関数を使えば簡単ですね。 #include<stdio.h> #include<math.h> int main(){ double nowX=0,nowY=0,len; int dr,r=90; while(1){ scanf("%lf,%d",&len,&dr); if(len==0&&dr==0)break; nowX+=len*cos(r/180.0*M_PI); nowY+=len*sin(r/180.0*M_PI); r=r-dr; } printf("%d\n%d\n",(int)nowX,(int)nowY); } *問17 Caesar Cipher http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0017 シーザー暗号を復元する問題。 解法 一行丸ごと読み込んでthisやtheのほうをずらして探します、this,,,という単語を排除するために後ろに空白やピリオドをつけました。。 これも問15と同じくコードが膨らんでる、もうちょっと短くなりそうだけど? #include<stdio.h> #include<string.h> int main(){ char line[82]; while(gets(line)!=NULL){ char words[6][6]={"this ","the ","that ","this.","the.","that."}; int s; for(s=1;s<27;s++){ for(int j=0;j<6;j++){ for(int k=0;k<strlen(words[j])-1;k++){ words[j][k]=(words[j][k]-'a'+1)%26+'a'; } } bool hit=false; for(int j=0;j<6;j++){ if(strstr(line,words[j])!=NULL)hit=true; } if(hit==true)break; } s=26-s; for(int i=0;i<strlen(line);i++){ if(line[i]==' '||line[i]=='.')printf("%c",line[i]); else printf("%c",(line[i]-'a'+s)%26+'a'); } printf("\n"); } } *問18 Sorting Five Numbers http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0018 5つの数字を降順に出力するだけの問題。 解法 std::sortで一発。 #include<stdio.h> #include<algorithm> #include <functional> int main(){ int ns[5]; for(int i=0;i<5;i++)scanf("%d",&ns[i]); std::sort(ns,ns+5,std::greater<int>()); for(int i=0;i<5;i++)printf("%d%c",ns[i],i==4?'\n':' '); } *問19 Factorial http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0019 階上計算する問題。 解法 定義そのまま、double型を使えば2^51までの整数はきちんと問題なく計算できるのでこれで計算。 #include<stdio.h> int main(){ int n; scanf("%d",&n); double fact[21]; fact[0]=fact[1]=1; for(int i=2;i<=n;i++)fact[i]=fact[i-1]*i; printf("%.0lf\n",fact[n]); }

表示オプション

横に並べて表示:
変化行の前後のみ表示: