填涂颜色

题目描述

由数字0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。现要求把闭合圈内的所有空间都填写成2.例如:6X6的方阵(n=6),涂色前和涂色后的方阵如下:


0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1


0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1


输入输出格式

输入格式:
每组测试数据第一行一个整数:n。其中n(1<=n<=30)
接下来n行,由0和1组成的nXn的方阵。
方阵内只有一个闭合圈,圈内至少有一个0。

输出格式:
已经填好数字2的完整方阵。

输入输出样例

输入样例#1:
6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

输出样例#1:
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

说明
1<=n<=30
.
.
.
.
.
.
.
.

分析:

从思路上来说,这题其实挺简单的。对于任何一个在圈圈内部的点,他的正上方,正下方,正左边,正右边都至少有一个1.只有这样他才能被判定是在圈内部。example(举了一个长方形的例子,正方形也同理。)

11111000

100010B0

10A01111

10000001

11111111

对于在框内的A来说他的正上,正下,正左,正右都有一个1.所以就可以判断他在方框内部;而对于B,他的上方和右边都没有1,就说明他不在框中。

由于这道题数据比较弱(只有30*30),*所以在不用任何算法的情况下纯粹的暴力模拟所有点在时间上也绰绰有余。

算法上对每个点(特别地,一定要判断这个点本身是不是1.如果他本身就是1,则跳过以下所有步骤)用四个repeat。分别用于枚举他的四个方向有没有1.如果四个方向都有1,这个点赋值为2.
.
.
.
.
.
.
.

程序:
var
a:array[0..31,0..31]of longint;
n,i,j,k:longint;

procedure init;
begin
    read(n);
    for i:=0 to n+1 do
    begin
        a[0,i]:=-1;a[i,0]:=-1;
        a[n+1,i]:=-1;a[i,n+1]:=-1;
    end;
    for i:=1 to n do
    for j:=1 to n do
    read(a[i,j]);
end;

procedure main;
begin
    for i:=1 to n do
    for j:=1 to n do
    begin
        k:=0;
        if a[i,j]=0 then
        begin
            repeat
                 k:=k+1;
            until (a[i-k,j]>0)or(a[i-k,j]=-1);
            if a[i-k,j]>0 then
            begin
                k:=0;
                repeat
                     k:=k+1;
                until (a[i+k,j]>0)or(a[i+k,j]=-1);
                if a[i+k,j]>0 then
                begin
                    k:=0;
                    repeat
                         k:=k+1;
                    until (a[i,j+k]>0)or(a[i,j+k]=-1);
                    if a[i,j+k]>0 then
                    begin
                        k:=0;
                        repeat
                             k:=k+1;
                        until (a[i,j-k]>0)or(a[i,j-k]=-1);
                        if a[i,j-k]>0 then a[i,j]:=2;
                    end;
                end;
            end;
        end;
    end;

end;

procedure print;
begin
    for i:=1 to n do
    begin
        for j:=1 to n do
        write(a[i,j],' ');
        writeln;
    end;
end;

begin
    init;
    main;
    print;
end.

原文地址:https://www.cnblogs.com/YYC-0304/p/9499996.html