ABC303-A
問題概要
2つの文字列が与えられる。二つは、oが0に、1がlに互いに入れ替わっているかもしれないほかは同じか。
解答
n=gets.to_i
s=gets.chomp
t=gets.chomp
n.times do |i|
if !(s[i]==t[i] || (s[i]=="1" && t[i]=="l" || s[i]=="l" && t[i]=="1") || (s[i]=="0" && t[i]=="o" || s[i]=="o" && t[i]=="0"))
puts "No"
exit
end
end
puts "Yes"
上が本番で提出したコード。Cで書いたのが以下。
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 5
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
int n=readint(s1);
free(s1);
char *s2=(char*)malloc(sizeof(char)*(n+2));
if(s2==NULL){
printf("memory allocation to s2 failed\n");
exit(1);
}
char *ts2=fgets(s2,n+2,stdin);
if(ts2==NULL){
printf("fgets(s2) failed\n");
exit(1);
}
char *s3=(char*)malloc(sizeof(char)*(n+2));
if(s3==NULL){
printf("memory allocation to s2 failed\n");
exit(1);
}
char *ts3=fgets(s3,n+2,stdin);
if(ts3==NULL){
printf("fgets(s3) failed\n");
exit(1);
}
int i=0;
while(i<n){
if (*(s2+i) != *(s3+i)){
if(!((*(s2+i)==108 && *(s3+i)==49) || (*(s2+i)==49 && *(s3+i)==108) || (*(s2+i)==111 && *(s3+i)==48) || (*(s2+i)==48 && *(s3+i)==111))){
printf("No\n");
exit(0);
}
}
i++;
}
printf("Yes\n");
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;
}
各文字を2倍に
ABC306-A
問題概要
与えられた文字列の各文字を2個ずつ連結した新しい文字列を出力せよ。
解答
n=gets.to_i
s=gets.chomp
ss=[]
n.times do |i|
ss[2*i]=ss[2*i+1]=s[i]
end
puts ss.join("")
上が本番で提出したコード。Cで書いたのが以下。
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 4
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
int n=readint(s1);
free(s1);
char *s2=(char*)malloc(sizeof(char)*(n+2));
if(s2==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts2=fgets(s2,n+2,stdin);
if(ts2==NULL){
printf("fgets(s2) failed\n");
exit(1);
}
// printf("n=%d\n",n);
// printf("s=%s\n",s2);
for(int i=0;i<n;i++){
printf("%c",*(s2+i));
printf("%c",*(s2+i));
}
free(s2);
printf("\n");
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;
}
二つの文字列の組み合わせで回文が作れるか
ABC307-B
問題概要
文字列の配列が与えられる。2つの文字列の組み合わせで回文を作ることができるか。
解答
n=gets.to_i
strs=[]
n.times do |i|
strs[i]=gets.chomp
end
n.times do |i|
flag2=false
n.times do |j|
if i==j
next
end
flag1=true
s=strs[i]+strs[j]
sz=strs[i].size+strs[j].size
(sz/2).times do |k|
if s[k]!=s[sz-1-k]
flag1=false
break
end
end
if flag1==true
puts "Yes"
exit
end
end
end
puts "No"
二重ループを回して全ての組み合わせを試している。
上が本番で提出したコード。Cで書いたのが以下。
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 5
#define N3 50
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
int n=readint(s1);
free(s1);
char *s2=(char*)malloc(sizeof(char)*n*(N3+1));
if(s2==NULL){
printf("memory allocation to s2 failed\n");
exit(1);
}
for(int i=0;i<n;i++){
char *s3=(char*)malloc(sizeof(char)*(N3+2));
if(s3==NULL){
printf("memory allocation to s3 failed\n");
exit(1);
}
char *ts3=fgets(s3,N3+2,stdin);
if(ts3==NULL){
printf("fgets(s3(%d)) failed\n",i);
exit(1);
}
int j=0;
while(*(s3+j)>=97 && *(s3+j)<=122){
*(s2+i*(N3+1)+j)=*(s3+j);
j++;
}
*(s2+i*(N3+1)+j)=0;
free(s3);
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==j)continue;
char *s4=(char*)malloc(sizeof(char)*(N3*2+1));
if(s4==NULL){
printf("memory allocation to s4 failed\n");
exit(1);
}
int k=0;
while(*(s2+i*(N3+1)+k)!=0){
*(s4+k)=*(s2+i*(N3+1)+k);
k++;
}
int l=0;
while(*(s2+j*(N3+1)+l)!=0){
*(s4+k)=*(s2+j*(N3+1)+l);
k++; l++;
}
*(s4+k)=0;
int flag=1;
// printf("i=%d j=%d s4=%s",i,j,s4);
for(int h=0;h<k/2;h++){
if(*(s4+h)!=*(s4+k-1-h)){
flag=0;
break;
}
}
if(flag==1){
printf("Yes\n");
exit(0);
}
free(s4);
}
}
printf("No\n");
free(s2);
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;
}
最初、読み込んだ文字列(s3)の終端の判定は、while(*(s3+j)!=0 && *(s3+j)!="\n")としていたのだが、そうするとなぜか改行文字が入ってしまうので、上記のコードのようにした。
ABC312-A
問題概要
標準入力から文字列が与えられる。その文字列は、問題文に与えられる文字列の一覧に含まれるか。
解答
s=gets.chomp
a=["ACE","BDF","CEG","DFA","EGB","FAC","GBD"]
a.each do |it|
if it==s
puts "Yes"
exit
end
end
puts "No"
上が本番で提出したコード。Cで書いたのが以下。
int scmp1(char* s, char* t, int n);
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 5
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
*(s1+3)=0;
// printf("s=%s\n",s1);
const char *strs[]={
"ACE","BDF","CEG","DFA","EGB","FAC","GBD"
};
for(int i=0;i<7;i++){
if(scmp1(*(strs+i),s1,3)==0){
printf("Yes\n");
exit(0);
}
}
printf("No");
free(s1);
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 scmp1(char* s, char* t, int n){
int i=0;
while(1){
if (*(s+i)==0 && *(t+i)==0) return 0;
else if (*(t+i)!=*(s+i)) return (*(s+i)-*(t+i));
else i++;
if(i>=n+1){
printf("s=%s, t=%s, i=%d\n",s,t,i);
printf("Comparing failed.\n");
}
}
}
特定の文字の削除
ABC315-A
問題概要
与えられた文字列から母音を取り除いて出力せよ。
解答
vowels=["a","e","i","o","u"]
s=gets.chomp.split("")
s.delete_if {|a| vowels.include?(a)}
puts s.join("")
上が本番で提出したコード。Cで書いたのが以下。
#include<stdio.h>
#include<stdlib.h>
#define N1 102
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
int i=0,j=0;
while(*(s1+i)!=0){
if(*(s1+i)==97 || *(s1+i)==101 || *(s1+i)==105 || *(s1+i)==111 || *(s1+i)==117){
//printf("%d: vowel\n",i);
i++;
}else{
//printf("%d: consonant\n",i);
*(s1+j)=*(s1+i); i++; j++;
}
}
*(s1+j)=0;
printf("%s\n",s1);
free(s1);
}
(保留中)
ABC320-B
問題概要
与えられた文字列のうち、回文となっている最長の連続部分列の長さを求めよ。
解答
まず、以下は本番で提出して1個だけWAになったコード。本番中にはどうしても原因がわからなかった。
s=gets.chomp.split("")
n=s.size
max=0
(0...n).each do |i|
(i...n).each do |j|
t=0
k=j-i+1
k.times do |l|
if s[i+l]!=s[j-l]
break
else
t+=1
end
end
# puts "#{i} #{j} #{k} #{t}"
max=[max,t].max
end
end
puts max
testcase04.txtでWAになっているので、後でその内容を見たところ、
UYWZYYUZUYUUZUYUZZYYZUZZUYYZWUZUYZUYZWZUYZWYUZZZUZYZYYUYYY
となっており、正解は5。一方、上記コードでは結果が6になる。
この問題は、一旦お預け。
検索
ABC322-A
問題概要
与えられた文字列の中でABCが初めて連続な部分文字列として現れる位置を出力せよ。
解答
n=gets.to_i
s=gets.chomp.split("")
(0..(n-3)).each do |i|
if s[i]=="A" && s[i+1]=="B" && s[i+2]=="C"
puts i+1
exit
end
end
puts -1
上が本番で提出したコード。Cで書いたのが以下。
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 5
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
int n=readint(s1);
free(s1);
char *s2=(char*)malloc(sizeof(char)*(n+2));
if(s2==NULL){
printf("memory allocation to s2 failed\n");
exit(1);
}
char *ts2=fgets(s2,n+2,stdin);
if(ts2==NULL){
printf("fgets(s2) failed\n");
exit(1);
}
int i=0;
while(i<n-2){
if(*(s2+i)==65 && *(s2+i+1)==66 && *(s2+i+2)==67){
printf("%d\n",i+1);
exit(0);
}else{
i++;
}
}
printf("%d\n",-1);
free(s2);
}
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;
}
前方一致・後方一致
ABC322-B
問題概要
2つの文字列 s, t が与えられる。sの文字数をnとして、sがtの先頭からn文字、末尾からn文字に、ともに一致するならば0、先頭からのみ一致するならば1、末尾からのみ一致するならば、2、どちらにも一致しなければ3 を出力せよ。
解答
n,m=gets.chomp.split(" ").map(&:to_i)
s=gets.chomp.split("")
t=gets.chomp.split("")
flag1=flag2=true
n.times do |i|
if s[i]!=t[i]
flag1=false
end
end
n.times do |i|
if s[i]!=t[m-n+i]
flag2=false
end
end
if flag1==true && flag2==true
puts 0
elsif flag1==true && flag2==false
puts 1
elsif flag1==false && flag2==true
puts 2
elsif flag1==false && flag2==false
puts 3
end
上が本番で提出したコード。Cで書いたのが以下。
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 9
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
int n=readint(s1);
int i=0;
while(*(s1+i)>=48 && *(s1+i)<=57){
i++;
}
i++;
int m=readint(s1+i);
free(s1);
char* s2=(char*)malloc(sizeof(char)*(n+2));
if(s2==NULL){
printf("memory allocation to s2 failed\n");
exit(1);
}
char* ts2=fgets(s2,n+2,stdin);
if(ts2==NULL){
printf("fgets(s2) failed\n");
exit(1);
}
char *s3=(char*)malloc(sizeof(char)*(m+2));
if(s3==NULL){
printf("memory allocation to s3 failed\n");
exit(1);
}
char *ts3=fgets(s3,m+2,stdin);
if(ts3==NULL){
printf("fgets(s3) failed\n");
exit(1);
}
// printf("n=%d m=%d\n",n,m);
// printf("%s\n",s2);
// printf("%s\n",s3);
int flag_pre=1,flag_post=1;
for(i=0;i<n;i++){
if(*(s2+i)!=*(s3+i)){
flag_pre=0;
break;
}
}
for(i=0;i<n;i++){
if(*(s2+i)!=*(s3+m-n+i)){
flag_post=0;
break;
}
}
int ans=3;
if (flag_pre==1 && flag_post==1)ans=0;
else if (flag_pre==1)ans=1;
else if (flag_post==1)ans=2;
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;
}
ABC323-A
問題概要
0と1からなる長さ16の文字列Sが与えられる。2以上16以下のすべての偶数iについて Sのi文字目が0か。
解答
s=gets.chomp.split("")
(1..8).each do |i|
if s[2*i-1]!="0"
puts "No"
exit
end
end
puts "Yes"
上が本番で提出したコード。Cで書いたのが以下。
#include<stdio.h>
#include<stdlib.h>
#define N1 18
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
// printf("%s",s1);
int i=0;
while(i<8){
if(*(s1+2*i+1)!=48){
printf("No\n");
exit(0);
}
i++;
}
printf("Yes\n");
return 0;
}
ABC325-A
問題概要
2つの文字列S,Tがスペース区切りで与えられる。S+(スペース)+"san"を出力せよ。
解答
sei,mei=gets.chomp.split(" ")
ans=sei+" san"
puts ans
上が本番で提出したコード。Cで書いたのが以下。
sei,mei=gets.chomp.split(" ")
ans=sei+" san"
puts ans
ABC327-A
問題概要
与えられた文字列の中にaとbが連続している(順序は不問)ところがあるか。
解答
n=gets.to_i
s=gets.chomp
(1...n).each do |i|
if s[i]=="a" && s[i-1]=="b" || s[i]=="b" && s[i-1]=="a"
puts "Yes"
exit
end
end
puts "No"
上が本番で提出したコード。Cで書いたのが以下。
int readint(char *s);
#include<stdio.h>
#include<stdlib.h>
#define N1 102
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
int n=readint(s1);
free(s1);
char *s2=(char*)malloc(sizeof(char)*(n+2));
if(s2==NULL){
printf("memory allocation to s2 failed\n");
exit(1);
}
char *ts2=fgets(s2,n+2,stdin);
if(ts2==NULL){
printf("fgets(s2) failed\n");
exit(1);
}
int i=0;
while(i<N1-1){
if ((*(s2+i)==97 && *(s2+i+1)==98) || (*(s2+i)==98 && *(s2+i+1)==97)){
printf("Yes\n");
exit(0);
}
i++;
}
printf("No\n");
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;
}
ABC329-A
問題概要
与えられた文字列を一文字ずつ空白区切りにして出力せよ。
解答
s=gets.chomp.split("")
puts s.join(" ")
上が本番で提出したコード。Cで書いたのが以下。
#include<stdio.h>
#include<stdlib.h>
#define N1 102
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
// printf("%s",s1);
int i=0,length=0;
while(i<N1-1 && *(s1+i)!=0){
i++;
length++;
}
i=0;
while(i<length-1){
printf("%c",*(s1+i));
printf("%c",32);
i++;
}
printf("%c",*(s1+i));
printf("\n");
return 0;
}
ABC339-A
問題概要
与えられた文字列の中には、少なくとも一つの . がある。最後の . より後の部分を切り出して出力せよ。
解答
s=gets.chomp
n=s.size
start=0
(n-1).downto(0).each do |i|
if s[i]=="."
start=i
break
end
end
puts s.slice(start+1,n-start)
上が本番の提出コード。(この日は足の怪我で仕事をお休みしたため、久しぶりの本番。)
Cで書いたのが以下。
#include<stdio.h>
#include<stdlib.h>
#define N1 102
int main(void){
char *s1=(char*)malloc(sizeof(char)*N1);
if(s1==NULL){
printf("memory allocation to s1 failed\n");
exit(1);
}
char *ts1=fgets(s1,N1,stdin);
if(ts1==NULL){
printf("fgets(s1) failed\n");
exit(1);
}
// printf("%s",s1);
int i=0,length=0;
while(i<N1-1 && *(s1+i)!=0){
i++;
length++;
}
i=length-1;
int period;
while(i>=0){
if(*(s1+i)==46){
period=i;
break;
}
i--;
}
i++;
for(;i<length;i++)
printf("%c",*(s1+i));
printf("\n");
return 0;
}
0 件のコメント:
コメントを投稿