試験_2015_3描画CSP(試験CSPにおけるBFSアプリケーションシナリオ)

概要

トピックの概要

BFSアルゴリズムは比較的単純かつ基本的なアルゴリズムですが、理由は多次元空間マップに対処する上での問題のいくつかに対処するため、実装が容易で、頻繁に多くのプログラミングタイトルに登場します。彼らは条件の空間と時間の複雑さにアルゴリズムを証明することができれば、BFS DFSアルゴリズムまたは類似を考案した場合、問題を解決するには満たされている、我々は決定的達成することができます。あなたには、いくつかのデータを満たすことができないことがわかり、なし他の良いアイデアことなく、スコアの一部を取得する方法として、CSPで使用することができます。

オリジナルタイトル説明

問題の説明
描画するASCII文字とは面白いもので、芸術の形成されたものは、ASCIIアートとして知られています。
:これは、次の2つの操作をサポートするためのプログラムを描画ASCII文字での問題をプログラミングする必要が
1、線を引く:2つのエンドポイントの座標を与えられ、2つの端点を結ぶ線分を描画します。各セグメントの単純タイトルを確保するために、水平または垂直に描かれています。キャラクターとのレベルのセグメント-文字と垂直線を描画する|描画します。特定の位置、代わり+キャラクタとの交点の位置に水平線と垂直線分交差する場合。
図2に示すように、充填:充填は、充填位置に隣接する文字で、開始位置から、充填される開始位置座標と文字のニーズを与えられた、またはそれがキャンバス絵のエッジを検出するまでされ、良好なラインを有しています。唯一の垂直方向と水平方向の4つの方向に隣接した位置を考慮する必要があります注意してください。

入力

最初の行は三つの整数m、nおよびqは含まれています。mおよびnは文字単位で、キャンバスの幅と高さを表しています。qは描画操作の数を表しています。
行Q + 1への第2行は、各行は二つの形態の一つです。

  • 0 X1、Y1×2 Y2は:ラインの操作、(X1、Y1)と(X2、Y2)を示すビデオセグメントの両端であるか、または満たすX1 = X2及びY1≠Y2とY1 = Y2、またはX 1≠X 2。
  • 1 XYCは:(x、y)は、既存のセグメント上に落下しないことが保証開始位置であり、充填動作を示し、Cは文字を埋めるために、それは敏感です。

カンバス座標(0、0)の位置の左下隅には、yが増加上方座標、x座標が増加する方向の右側にあります。このQ動作が順次順序提示されたデータで行わ。すべてのポジションは当初キャンバス文字です。(小数点)。

出力

m個の文字の出力線を順次qが得られ、これらの操作を行った結果を示す図で、Nが存在します。

Oケース

サンプル
入力:

4 2 3
1 0 0 B
0 1 0 2 0
1 0 0 A

出力:

AAAA
A ---- A

サンプル2
入力:

9 13 16
0 3 1 12 1
0 12 1 12 3
0 12 3 6 3
0 6 3 6 9
0 6 9 12 9
0 12 9 12 11
0 12 11 3 11
0 3 11 3 1
1 4 2 C

出力:
ここに画像を挿入説明

タイトルリピート

キャンバスのサイズ(幅、長さM×N)の演算の数Qとなるように出力し、設定します。そして、キャンバスのすべてのポイントは、「」「」に無線を描画した初期状態に初期化されます。
:そこに2つの操作がされている
オブジェクトを操作プロンプトは入力(X1、Y1)から(X2、Y2)の操作を描く0行である、および特定によって描かれた線画の入力データ対象の完了を保証するために注意必見×1 == X2またはY1 == y2が、そこにある直線が、あります。
プロンプト動作は1であり、所定の出発点(x、y)は入力パッドの文字から始まる、充填操作で、またはキャンバス引かれた境界線の充填停止に達します。(明らかに改訂迷路)
出力、各文字位置の出力、以下の状況:
1、垂直線、水平線、出力は「+」
2は、いかなる水平垂直出力はありません「 - 」
「|」3が、そこには水平、垂直出力されない
充填、出力充填文字と4、なし水平なし垂直ライン、
「」5、無水平なし垂直線、塗りなし、出力。
出力ことに留意すべきですキャンバスは出力出力のパラメータを通過するために注意を払うように、キャンバスの上から順です。
文字列に関連した背景とトピックは、文字列が問題のように見えるが、長いとほぼ問題を理解するよう、私たちは、これは典型的なBFSトピックであることがわかります。主な研究は、データ・ストレージ・スキルのためのものであり、同じ問題と迷路ボードの問題のシナリオに変換した後、BFSの一部にすることができ、アルゴリズムの設計に多くの困難がありません。

問題解決のためのアイデア

概要アイデア

ここでは、入力と出力部分だけ一部の特殊な文、プラスについて説明されていません。
一定の規定が異なるだけな状況で、直線を引くとラインを格納するため、ライン描画処理について、アルゴリズムの設計には困難がありません。次のようにライン描画機能の操作は次のとおりです。

void make_line(int x_1,int y_1,int x_2,int y_2)
{
    if(x_1==x_2)//纵向划线
    {
        if(y_1==y_2)//不划线
        return;
        else if(y_1>y_2)//向下划线
        {
            for(int i=y_2;i<=y_1;i++)
            {
                a[x_1][i].long_direct=1;
            }
        }
        else
        {
            for(int i=y_1;i<=y_2;i++)//向上划线
            {
                a[x_1][i].long_direct=1;
            }
        }
    }
    else if(y_1==y_2)//横向划线
    {
        if(x_1>x_2)//向左划线
        {
            for(int i=x_2;i<=x_1;i++)
            {
                a[i][y_1].wide_direct=1;
            }
        }
        else
        {
            for(int i=x_1;i<=x_2;i++)
            {
                a[i][y_1].wide_direct=1;
            }
        }   
    }
}

一部の充填では、コアアルゴリズムは、ボードの迷路です。それはさらにいくつかの境界条件は、以下のことに留意されたい:
1、唯一BFS XY正の軸、すなわち> = 0点の水平および垂直座標を満たすためにBFSを満たすために、実行
2において、点はBFSキャンバスを超えることはできません範囲は、水平および垂直座標は<幅、長さ満たす
。3満たすフラグ== 0をスクライブ水平方向および垂直方向のスクライブ中に遭遇するだけBFSは、唯一のバックカバー充填にキューにポイントを押し、そして注意を払うに充填の前インチ
次のようにコードの一部を充填:

void BFS_fill(int start_x,int start_y,char filling)
{
    if(a[start_x][start_y].wide_direct==1 || a[start_x][start_y].long_direct==1)
    {
        return;
    }
    a[start_x][start_y].filling=filling;

    pos start;
    start.x=start_x;
    start.y=start_y;
    q.push(start);
    while(!q.empty())
    {
        pos node=q.front();
        q.pop();

        for(int i=0;i<4;i++)
        {
            int new_node_x=node.x+dx[i];
            int new_node_y=node.y+dy[i];
            if(a[new_node_x][new_node_y].wide_direct==0 && a[new_node_x][new_node_y].long_direct==0 && a[new_node_x][new_node_y].filling!=filling && new_node_x<wideth && new_node_y<length && new_node_x>=0 && new_node_y>=0)
            {
                a[new_node_x][new_node_y].filling=filling;
                pos new_node;
                new_node.x=new_node_x;
                new_node.y=new_node_y;
                q.push(new_node);
            }
        }
    }
}

概要

この質問はかなり水、良い様々な境界条件への配慮限り、ロールオーバーそうではありません。

トピックソース(C ++)

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;

struct point
{
    int wide_direct;//横向线
    int long_direct;//纵向线
    char filling;
};

struct pos
{
    int x;
    int y;
};

int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};

point a[101][101];
int wideth,length=0;
queue<pos> q;

void BFS_fill(int start_x,int start_y,char filling)
{
    if(a[start_x][start_y].wide_direct==1 || a[start_x][start_y].long_direct==1)
    {
        return;
    }
    a[start_x][start_y].filling=filling;

    pos start;
    start.x=start_x;
    start.y=start_y;
    q.push(start);
    while(!q.empty())
    {
        pos node=q.front();
        q.pop();

        for(int i=0;i<4;i++)
        {
            int new_node_x=node.x+dx[i];
            int new_node_y=node.y+dy[i];
            if(a[new_node_x][new_node_y].wide_direct==0 && a[new_node_x][new_node_y].long_direct==0 && a[new_node_x][new_node_y].filling!=filling && new_node_x<wideth && new_node_y<length && new_node_x>=0 && new_node_y>=0)
            {
                a[new_node_x][new_node_y].filling=filling;
                pos new_node;
                new_node.x=new_node_x;
                new_node.y=new_node_y;
                q.push(new_node);
            }
        }
    }
}
void make_line(int x_1,int y_1,int x_2,int y_2)
{
    if(x_1==x_2)//纵向划线
    {
        if(y_1==y_2)//不划线
        return;
        else if(y_1>y_2)//向下划线
        {
            for(int i=y_2;i<=y_1;i++)
            {
                a[x_1][i].long_direct=1;
            }
        }
        else
        {
            for(int i=y_1;i<=y_2;i++)//向上划线
            {
                a[x_1][i].long_direct=1;
            }
        }
    }
    else if(y_1==y_2)//横向划线
    {
        if(x_1>x_2)//向左划线
        {
            for(int i=x_2;i<=x_1;i++)
            {
                a[i][y_1].wide_direct=1;
            }
        }
        else
        {
            for(int i=x_1;i<=x_2;i++)
            {
                a[i][y_1].wide_direct=1;
            }
        }   
    }
}
void output()
{
    for(int j=length-1;j>=0;j--)
    {
        for(int i=0;i<wideth;i++)
            {
                if(a[i][j].long_direct==1 && a[i][j].wide_direct==1)
                printf("+");
                else if(a[i][j].long_direct==1 && a[i][j].wide_direct==0)
                printf("|");
                else if(a[i][j].long_direct==0 && a[i][j].wide_direct==1)
                printf("-");
                else if(a[i][j].long_direct==0 && a[i][j].wide_direct==0)
                printf("%c",a[i][j].filling);
            }
            printf("\n");
    }
}
int main()
{
    int done_num=0;
    int control_num=0;
    int x_1,x_2,y_1,y_2=0;
    int x,y=0;
    char str;
    scanf("%d %d %d",&wideth,&length,&done_num);
    for(int i=0;i<wideth;i++)
        for(int j=0;j<length;j++)
            a[i][j].long_direct=0,a[i][j].wide_direct=0,a[i][j].filling='.';
    for(int i=0;i<done_num;i++)
    {
        scanf("%d",&control_num);
        if(control_num==0)
        {
            scanf("%d %d %d %d",&x_1,&y_1,&x_2,&y_2);
            make_line(x_1,y_1,x_2,y_2);
        }
        else
        {
            scanf("%d %d %c",&x,&y,&str);
            BFS_fill(x,y,str);
        }
    }
    output();
    return 0;
}
公開された17元の記事 ウォンの賞賛2 ビュー1661

おすすめ

転載: blog.csdn.net/qq_43942251/article/details/104937139