Codingame『Sandpile addition』

砂場用 さくさくあそび砂 20kg(13.3L)【放射線量報告書付き】
www.codingame.com


カタストロフィー現象って言うんだっけ?

 高さが4以上なら-4して上下左右に+1すればいいんだから、特に難しくない。
n×n配列内に高さ4以上がある事をどうやって知るのかが工夫のしどころかな?


 誰でも思いつくような工夫だけど、
地ならしと高さチェックで配列を2ループさせる所を、1ループでできるようにした。


コード
using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;

/**
 * Auto-generated code below aims at helping you parse
 * the standard input according to the problem statement.
 **/
class Solution
{
    static void Main(string[] args)
    {
        SandBox sb = new SandBox();
        sb.LandLeveler();
        sb.Draw();
    }
}

public class SandBox
{
    //砂場のサイズ
    private int size;
    //砂場の状態
    private int[,] sandState;

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public SandBox()
    {
        this.InitSandBox();
    }

    /// <summary>
    /// 地ならし
    /// </summary>
    public void LandLeveler()
    {
        while (true)
        {
            bool over3 = false;

            for (int y = 0; y < this.size; y++)
            {
                for (int x = 0; x < this.size; x++)
                {
                    if (this.sandState[x, y] > 3)
                    {
                        this.sandState[x, y] -= 4;
                        over3 = over3 | this.DistributeSand(x - 1, y);
                        over3 = over3 | this.DistributeSand(x + 1, y);
                        over3 = over3 | this.DistributeSand(x, y - 1);
                        over3 = over3 | this.DistributeSand(x, y + 1);
                    }
                }
            }

            if (over3 == false)
            {
                break;
            }
        }
    }

    /// <summary>
    /// 砂の振り分け
    /// </summary>
    private bool DistributeSand(int x, int y)
    {
        if (x < this.size & x >= 0 & y < this.size & y >= 0)
        {
            if ((++this.sandState[x, y]) > 3)
            {
                return true;
            }
        }

        return false;
    }

    /// <summary>
    /// 砂場の初期化
    /// </summary>
    private void InitSandBox()
    {
        this.PrepareSandBox();
        this.ReadSandBox();
    }

    /// <summary>
    /// 砂場の準備
    /// </summary>
    private void PrepareSandBox()
    {
        this.size = int.Parse(Console.ReadLine());
        this.sandState = new int[this.size, this.size];
    }

    /// <summary>
    /// 砂場の読み込み
    /// </summary>
    private void ReadSandBox()
    {
        for (int p = 0; p < 2; p++)
        {
            for (int y = 0; y < this.size; y++)
            {
                string row = Console.ReadLine();

                for (int x = 0; x < this.size; x++)
                {
                    this.sandState[x, y] += (int)(row[x] - '0');
                }
            }
        }
    }

    /// <summary>
    /// 砂場の描画
    /// </summary>
    public void Draw()
    {
        for (int y = 0; y < this.size; y++)
        {
            for (int x = 0; x < this.size; x++)
            {
                Console.Write(this.sandState[x, y]);
            }
            Console.WriteLine("");
        }
    }
}