ホーム » 2025 » 4月 » 24

日別アーカイブ: 2025年4月24日

2025年4月
 12345
6789101112
13141516171819
20212223242526
27282930  

検索・リンク

創造工学演習・予備実験(2)・8queen

創造工学演習の予備実験 part 2 として、Flood Fill , 8queen にチャレンジしてみる。

Flood fill アルゴリズム

前の問題は、今年度のプログラミングコンテストの課題のパズルとは、方向性が違うので、今年度のプロコンの競技部門にちょっとだけ近い2次元フィールドのパズルネタで演習。(Wikipedia Flood-fill参照)

以下の image のような2次元配列が与えられたら、指定座標(x,y)を中心に周囲を塗りつぶす処理を作成せよ。

include <stdio.h>

// *は壁 SPCは白 この領域の指定位置を#で塗りつぶす。                            
char image1[10][10] = { // (4,4)始点で塗りつぶし後
        "*********" ,   // ********* 
        "*   *   *" ,   // *   *###*
        "*   *   *" ,   // *   *###*
        "*  *    *" ,   // *  *####*
        "***   ***" ,   // ***###***
        "*    *  *" ,   // *####*  *
        "*   *   *" ,   // *###*   *
        "*   *   *" ,   // *###*   *
        "*********" ,   // *********
} ;

char image2[10][10] = { // 応用問題用の画像例
        "*********" ,   //  *   のような隙間は通り抜けられる
        "*   *   *" ,   // *    ようにするにはどうすればいい?
        "*  **   *" ,   //   **
        "* **    *" ,   //  **  これは通り抜けられない
        "***   ***" ,   // **
        "*    *  *" ,
        "*   *   *" ,
        "*   *   *" ,
        "*********" ,
} ;

// 盤面を表示                                                                   
void print_image( char image[10][10] ) {
  for( int y = 0 ; y < 9 ; y++ ) {
    for( int x = 0 ; x < 9 ; x++ ) {
      printf( "%c" , image[y][x] ) ;
    }
    printf( "\n" ) ;
  }
}

// 再帰呼び出しを使った flud_fill アルゴリズム                                  
void flood_fill( char image[10][10] , int x , int y , char fill ) {
  // image: 塗りつぶす画像
  // x,y:   塗りつぶす場所
  // fill:  書き込む文字
  // 指定座標が空白なら
  if ( image[y][x] == ' ' ) {
    // その座標を埋める
    image[y][x] = fill ;
    //////////////////////////////////////
    // ここに周囲をflud_fillする処理を書く  //
    ////////////////////////////////////// 
  }
}

int main() {
  print_image( image1 ) ;
  flood_fill( image1 , 4 , 4 , '#' ) ;
  print_image( image1 ) ;
  return 0 ;
}
import java.util.*;

public class Main {
    public static String[] image1 = {
        "*********" ,   // ********* 
        "*   *   *" ,   // *   *###*
        "*   *   *" ,   // *   *###*
        "*  *    *" ,   // *  *####*
        "***   ***" ,   // ***###***
        "*    *  *" ,   // *####*  *
        "*   *   *" ,   // *###*   *
        "*   *   *" ,   // *###*   *
        "*********" ,   // *********
    } ;
    // 文字配列を文字の2次元配列に変更
    public static char[][] map_from_string( String[] image ) {
        char[][] map = new char[ image.length ][ image[0].length() ] ;
        for( int i = 0 ; i < image.length ; i++ ) {
            for( int j = 0 ; j < image[ i ].length() ; j++ ) {
                map[ i ][ j ] = image[ i ].charAt( j ) ;
            }
        }
        return map ;
    }
    // 2次元配列を出力
    public static void print_image( char[][] map ) {
        for( int i = 0 ; i < map.length ; i++ ) {
            for( int j = 0 ; j < map[i].length ; j++ ) {
                System.out.print( map[ i ][ j ] ) ;
            }
            System.out.println() ;
        }
    }
    // 塗りつぶし処理
    public static void flood_fill( char[][] map , int x , int y , char c ) {
        if ( map[x][y] == ' ' ) {

            // 指定された場所に埋める文字を代入
            map[x][y] = c ;

            ////////////////////////////////////////////
            // ここに周囲を flood_fill する処理を書く //
            ////////////////////////////////////////////
        }
    }
    public static void main(String[] args) throws Exception {
        char[][] map = map_from_string( image1 ) ;
        print_image( map ) ;
        flood_fill( map , 4 , 4 , '#' ) ;
        print_image( map ) ;
    }
}

応用問題

Wikipediaのflood-fill のプログラムの説明のアルゴリズムでは、左図黒のような斜めに並んだブロックは、境界として通り抜けられないようにつくられている。

そこで、斜めに並んだブロックは通り抜けられるルールとした場合のプログラムを記述せよ。

レポート提出

レポートでは、指定長を辺の組み合わせで作るテーマか、Flood-fill のテーマのいずれかにて、以下の内容をまとめてレポートとして提出すること。

    • レポートの説明(自分の選んだテーマと自分なりの説明)
    • プログラムリスト
    • 動作確認の結果

N Queen

パズル問題の定番の8 Queen を考えてみる。

8 Queen とは、8×8のチェスの盤面に、8つの Queen をお互いに取られないように配置するパズル。

import java.util.*;

public class Main {
    public final static int size = 4 ;
    public static int[] board = new int[ size ] ;
    
    // できあがった盤面を表示する補助関数
    public static void print_board( int[] board ) {
        for( int i = 0 ; i < size ; i++ ) {
            for( int j = 0 ; j < board[ i ] ; j++ )
                System.out.print( "+ " ) ;
            System.out.print( "Q " ) ;
            for( int j = board[ i ] + 1 ; j < size ; j++ )
                System.out.print( "+ " ) ;
            System.out.println() ;
        }
        System.out.println() ;
    }
    
    // n_queen本体
    //   4 queen の boad 配列
    //   [ 1 3 0 2 ]
    //     + + Q +
    //     Q + + +
    //     + + + Q
    //     + Q + +
    public static void n_queen( int[] board , int n , int i ) {
        // nは盤面の大きさ
        // i列目のj行目に置く(i=2)
        // [ 1 3 j ? ]
        //   0 1 2 3
        // 0 + + + +
        // 1 Q + + +
        // 2 + +[Q]+ j=2
        // 3 + Q + +
        if ( i == n ) {
            // 右端まですべて埋まったら答えとして表示
            print_board( board ) ;
        } else {
            // j行目に置くのを試す
            for( int j = 0 ; j < size ; j++ ) {
                // 同じ行に置かれたものが無いか探す
                boolean flag = true ;
                for( int k = 0 ; k < i && flag ; k++ ) {
                    if ( board[ k ] == j )
                        flag = false ; // 同じ行にすでに置かれている
                }
                if ( flag ) {   // 同じ行が使われていなければ
                    // 斜め左上に向かってぶつかるQueenを探す
                    for( int u = j - 1 , h = i - 1 ; u >= 0 && h >= 0 && flag ; u-- , h-- ) {
                       if ( board[ h ] == u )
                            flag = false ;
                    }
                    // 斜め左下に向かってぶつかるQueenを探す
                    for( int d = j + 1 , h = i - 1 ; d < size && h >= 0 && flag ; d++ , h-- ) {
                        if ( board[ h ] == d )
                            flag = false ;
                    }
                    if ( flag ) {
                        // 左横、左斜め上、左斜め下にぶつかるQueenが無かったら、再帰
                        board[ i ] = j ;
                        n_queen( board , n , i + 1 ) ;
                    }
                }
            } 
        }
    }
    public static void main(String[] args) throws Exception {
        n_queen( board , size , 0 ) ;
        print_board( board ) ;
        
    }
}

システム

最新の投稿(電子情報)

アーカイブ

カテゴリー