paizaさんの、電脳少女プログラミング2088、楽しく解いてます。
レイミ可愛いし、検証中画面もかっこいい。
問題によってC言語で解いたりPythonで解いたりしてますが、
解いてみた投稿でC言語が少ない印象だったので、Cで書いたものを載せてみます。
リンクはこちら 電脳少女プログラミング2088
本記事投稿した後で、レイミちゃんからの指摘を反映して解き直したので、編集します。
反映した指摘内容は、配列のサイズを小さくできるはず、的な内容。
解き直し前は、ピクセルアートを読み込むときにスペースを除く処理をしないで済むように配列サイズをn*2で組んでいました。そこを改善しました。結果、ずいぶんすっきりしました。
#include <stdio.h>
#include <string.h>
int main(void){
// 自分の得意な言語で
// Let's チャレンジ!!
int n;
int i,j,k; //loop counter
int ans = 1;
char str[128];
fgets(str, sizeof(str), stdin);
sscanf(str, "%d", &n);
//ピクセルアートを読み込む
char art[n][n];
memset( art, 0x00, sizeof(art));
for( i=0; i<n; i++) {
fgets(str, sizeof(str), stdin);
for( j=0; j<n; j++) {
art[i][j] = str[j*2];
}
}
//左右対称か見ていく
for( k=0; k<n; k++){
for( i=0, j=n-1; i<n/2; i++, j--){
if( art[k][i] != art[k][j]) {
ans = 0;
break;
}
}
if( ans == 0) break;
}
if( ans == 0) {
printf("No\n");
} else {
printf("Yes\n");
}
return 0;
}
下記は改善前の記事です。
二次元配列に入力値をそのまんま読み込んで、
ループして一行ずつ、
iを行の先頭からのインデックス、jを行末からのインデックスとして、
両端から順々に比較していくだけです。
#include <stdio.h>
#include <string.h>
int main(void){
// 自分の得意な言語で
// Let's チャレンジ!!
int n;
int i,j,k; //loop counter
int ans = 1;
char str[1000];
fgets(str, sizeof(str), stdin);
sscanf(str, "%d", &n);
//ピクセルアートを読み込む
char art[n][n*2];
memset( art, 0x00, sizeof(art));
for( i=0; i<n; i++) {
fgets(str, sizeof(str), stdin);
strcpy( art[i], str);
}
//左右対称か見ていく
for( k=0; k<n; k++){
for( i=0, j=n*2-2; i<(n*2-1)/2; i++,j--){
if( art[k][i] != art[k][j]) {
ans = 0;
break;
}
}
if( ans==0) break;
}
if( ans == 0) {
printf("No\n");
} else {
printf("Yes\n");
}
return 0;
}
同じコードを提出しても、レイミちゃんから
「文字列の終端文字のこと、忘れんようにしようね!」
とか、
配列のサイズがn*2じゃなくn-1がいいんじゃないかとか配列サイズが大きいんじゃないかとかのご指摘がありました。
文字列の終端は止めてないけど意識はしてたし(でも止めるべきか)、
配列のサイズを小さくするなら確かに比較の回数減るけど、マップの読み込み時の処理量が増えるよね、と思いますが…その方がいいのかな?でもnの最大値が50なので大して気にする必要がない気もする…ご教示くださる方がいらっしゃったらありがたいです。