0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AOJ PG入門 #5

Posted at

はじめに

今回は初めて構造化プラグラムの問題を解いてみる。面白かったけど難しかった(-_-;)!!

問1.たてH cm よこ W cm の長方形を描くプログラムを作成して下さい。

1 cm × 1cm の長方形を '#'で表します。

  • 入力は複数のデータセットから構成されています。各データセットの形式は H W
  • H,Wがともに0のとき入力を終了
  • 各データセットについて、H × W 個の '#' で描かれた長方形を出力して下さい。各データセットの後に、1つの空行を入れて下さい。

PHP

AOJ.php
<?php

while (true) {
    fscanf(STDIN, "%d %d", $h, $w);
    if ($h == 0 && $w == 0) break;

    for ($j = 0; $j < $h; $j++) {
        for ($i = 0; $i < $w; $i++) {
            echo "#";
        }
        echo "\n";  // 各行の後に改行
    }
    echo "\n";  // データセットの後に空行を入れる
}

?>

別解

other.php
<?php
while (true) {
    list($H, $W) = array_map("intval", explode(' ', trim(fgets(STDIN))));
    if ($H == 0 && $W == 0) {
        break;
    }
    
    $line = str_repeat('#', $W) . "\n";
    $rectangle = str_repeat($line, $H);

    print($rectangle . "\n");
}
?>
  • str_repeat→指定した回数分繰り返した文字列を返す。第一引数に繰り返す文字列、第二引数にその回数

Java

AOJ.java
import java.util.Scanner;
public class Main{
    public static void main(String[]args){
        Scanner sc = new Scanner(System.in);
        while(true){
            int h = sc.nextInt();
            int w = sc.nextInt();
            if(h==0&&w==0)break;
            for(int j=0;j<h;j++){
                for(int i=0;i<w;i++){
                    System.out.print("#");
                }
                System.out.println();
            }
            System.out.println();
        }
        sc.close();
    }
}

問2.フレームの描画

以下のような、たてH cm よこ W cm の枠を描くプログラムを作成して下さい。

##########
#........#
#........#
#........#
#........#
##########
  • 入力は複数のデータセットから構成されています。各データセットの形式は H W
  • H, W がともに 0 のとき、入力の終わりとします。
  • 各データセットについて、たて H cm よこ W cm の枠を出力して下さい。各データセットの後に、1つの空行を入れて下さい。

PHP

AOJ.php
<?php
while(true){
    list($h,$w) = array_map("intval", explode(" ", trim(fgets(STDIN))));
    if($h == 0 && $w == 0) break;
    
    $line1 = str_repeat("#", $w) . "\n";
    $line2 = "#" . str_repeat(".", $w - 2) . "#\n";
    
    for($i = 0; $i < $h; $i++){
        if($i == 0 || $i == $h - 1){
            echo $line1;
        } else {
            echo $line2;
        }
    }
    echo "\n";
}
?>

Java

AOJ.java
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(true) {
            int h = sc.nextInt();
            int w = sc.nextInt();
            if(h == 0 && w == 0) break;
            
            // 上下の行を作成
            StringBuilder line1 = new StringBuilder();
            for(int j = 0; j < w; j++) {
                line1.append("#");
            }
            
            // 中間の行を作成
            StringBuilder line2 = new StringBuilder("#");
            for(int j = 0; j < w - 2; j++) {
                line2.append(".");
            }
            line2.append("#");
            
            for(int i = 0; i < h; i++) {
                if(i == 0 || i == h - 1) {
                    System.out.println(line1);
                } else {
                    System.out.println(line2);
                }
            }
            System.out.println();
        }
        sc.close();
    }
}
  • StringクラスのrepeatメソッドはJava11以降。今回は代わりにStringBuilderオブジェクトのappendメソッドを利用して文字列を連結

別解

other.java
import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner scan=new Scanner(System.in);
        while(true){
            int H=scan.nextInt();
            int W=scan.nextInt();
            if(H==0&&W==0)break;
            for(int i=0;i<H;i++){
                for(int j=0;j<W;j++){
                    if(i==0||i==H-1||j==0||j==W-1){
                        System.out.print('#');
                    }
                    else{
                        System.out.print('.');
                    }
                }
                System.out.println();
            }
            System.out.println();
        }
        scan.close();
    }
} 

問3.以下のような、たてH cm よこ W cm のチェック柄の長方形を描くプログラムを作成して下さい。

#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
//上図は、たて 6 cm よこ 10 cm の長方形
  • 入力は複数のデータセットから構成されています。各データセットの形式は H W
  • H, W がともに 0 のとき、入力の終わり
  • 各データセットについて、たて H cm よこ W cm の枠を出力して下さい。各データセットの後に、1つの空行を入れて下さい。

PHP

AOJ.php
<?php
while (true) {
    fscanf(STDIN, "%d %d", $h, $w);
    if ($h == 0 && $w == 0) break;

    //$line1 と $line2 を文字列として初期化し、ループの中で # や . を文字列として追加していく
    $line1 = "";
    $line2 = "";

    for ($i = 0; $i < $w; $i++) {
        if ($i % 2 == 0) {
            $line1 .= "#";
            $line2 .= ".";
        } else {
            $line1 .= ".";
            $line2 .= "#";
        }
    }

    for ($j = 0; $j < $h; $j++) {
        if ($j % 2 == 0) {
            echo $line1 . "\n";
        } else {
            echo $line2 . "\n";
        }
    }
    echo "\n"; // データセットの区切りとして空行を追加
}
?>
  • PHPで配列のサイズを指定したいとき→array_fill() / 配列を初期化してループで要素を追加
arr.php
array_fill('開始インデックス, 要素数, 初期値');

別解

other.php
<?php
while (true) {
    list($H, $W) = array_map("intval", explode(' ', trim(fgets(STDIN))));
    if ($H == 0 && $W == 0) {
        break;
    }
    
    $line1 = str_repeat('#.', (int) floor($W / 2)) . str_repeat('#', $W % 2) . "\n";
    $line2 = str_repeat('.#', (int) floor($W / 2)) . str_repeat('.', $W % 2) . "\n";
    $lines = $line1 . $line2;

    $board = str_repeat($lines, (int) floor($H / 2)) . str_repeat($line1, $H % 2);

    print($board . "\n");
}
?>
other2.php
while (($input = trim(fgets(STDIN))) !== "0 0") {
    list($h, $w) = array_map("intval", explode(" ", $input));

    $s1 = substr(str_repeat("#.", intdiv($w+1, 2)), 0, $w);
    $s2 = substr(str_repeat(".#", intdiv($w+1, 2)), 0, $w);

    for ($i = 0; $i < $h; $i++) {
        print(($i % 2 === 0 ? $s1 : $s2) . "\n");
    }

    print("\n");
}

  • subst関数→指定した文字列の一部を取得することができるPHPの組み込み関数
  • intdiv($w+1, 2) は第一引数を第二引数で割った商を求める関数
str.php
substr(対象文字列, 開始位置インデックス ,抽出する長さ)
  • mb_substrも、指定した文字列の一部を取得する関数だが、mb_substrは、開始位置、文字数の指定に加えて、文字列の文字コードの指定を行うことができる。対象文字列が日本語の場合こっちを使うのがいい。
  • substrがstr_repeatした文字列を切り取る関数と考えると、w が奇数の場合に切り取る部分が足りない→$w+1

Java

AOJ.java
import java.util.Scanner;
public class Main{
    public static void main(String[]args){
        Scanner sc = new Scanner(System.in);
        while(true){
            int h = sc.nextInt();
            int w = sc.nextInt();
            if(h==0&&w==0)break;
            
            for(int j = 0; j < h; j++){
                for(int i = 0; i < w; i++){
                    System.out.print((j+i)%2==0 ? "#" : ".");
                }
                System.out.println();
            }
            System.out.println();
        }
        sc.close();
    }
}
  • チェック柄(碁盤の目のような模様)は、隣接する行と列で交互に色が変わるパターン
行 / 列 0 1 2
0 # . #
1 . # .
2 # . #
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?