AtCoderのPAST    次のPASTの問題へ    前のPASTの問題へ

第3回PAST I 行列操作


問題へのリンク


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("2");
            WillReturn.Add("19");
            WillReturn.Add("4 1 1");
            WillReturn.Add("4 1 2");
            WillReturn.Add("4 2 1");
            WillReturn.Add("4 2 2");
            WillReturn.Add("3");
            WillReturn.Add("4 1 1");
            WillReturn.Add("4 1 2");
            WillReturn.Add("4 2 1");
            WillReturn.Add("4 2 2");
            WillReturn.Add("1 1 2");
            WillReturn.Add("4 1 1");
            WillReturn.Add("4 1 2");
            WillReturn.Add("4 2 1");
            WillReturn.Add("4 2 2");
            WillReturn.Add("2 2 1");
            WillReturn.Add("4 1 1");
            WillReturn.Add("4 1 2");
            WillReturn.Add("4 2 1");
            WillReturn.Add("4 2 2");
            //0
            //1
            //2
            //3
            //0
            //2
            //1
            //3
            //1
            //3
            //0
            //2
            //3
            //1
            //2
            //0
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("3");
            WillReturn.Add("9");
            WillReturn.Add("2 2 3");
            WillReturn.Add("3");
            WillReturn.Add("1 2 1");
            WillReturn.Add("2 3 2");
            WillReturn.Add("1 1 3");
            WillReturn.Add("3");
            WillReturn.Add("4 1 1");
            WillReturn.Add("4 2 2");
            WillReturn.Add("4 2 3");
            //1
            //6
            //8
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    struct QueryInfoDef
    {
        internal long Type;
        internal long A;
        internal long B;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();

        long[] wkArr = { };
        Action<string> SplitAct = pStr =>
            wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();

        long N = int.Parse(InputList[0]);
        long UB = N - 1;

        var QueryInfoList = new List<QueryInfoDef>();
        foreach (string EachStr in InputList.Skip(2)) {
            SplitAct(EachStr);
            QueryInfoDef WillAdd;
            long Type = wkArr[0];

            WillAdd.Type = Type;

            if (Type != 3) {
                WillAdd.A = wkArr[1] - 1;
                WillAdd.B = wkArr[2] - 1;
            }
            else {
                WillAdd.A = -1;
                WillAdd.B = -1;
            }
            QueryInfoList.Add(WillAdd);
        }

        // 列番号の配列
        long[] ColumnIndArr = new long[UB + 1];

        // 行番号の配列
        long[] RowIndArr = new long[UB + 1];

        for (long I = 0; I <= UB; I++) {
            ColumnIndArr[I] = I;
            RowIndArr[I] = I;
        }

        // 転置回数
        long TentiCnt = 0;

        long Cnt = 0;
        foreach (QueryInfoDef EachQueryInfo in QueryInfoList) {
            long Type = EachQueryInfo.Type;
            long A = EachQueryInfo.A;
            long B = EachQueryInfo.B;

            if (Type == 1) {
                if (TentiCnt % 2 == 0) ExecSwap(RowIndArr, A, B);
                else ExecSwap(ColumnIndArr, A, B);
            }
            if (Type == 2) {
                if (TentiCnt % 2 == 1) ExecSwap(RowIndArr, A, B);
                else ExecSwap(ColumnIndArr, A, B);
            }
            if (Type == 3) {
                TentiCnt++;
            }
            if (Type == 4) {
                if (TentiCnt % 2 == 0) {
                    long X = ColumnIndArr[B];
                    long Y = RowIndArr[A];
                    Console.WriteLine(X + N * Y);
                }
                else {
                    long X = RowIndArr[B];
                    long Y = ColumnIndArr[A];
                    Console.WriteLine(Y + N * X);
                }
            }
        }
    }

    // 引数の配列の、2つの添字の値を交換
    static void ExecSwap(long[] pArr, long pInd1, long pInd2)
    {
        long Saved = pArr[pInd1];
        pArr[pInd1] = pArr[pInd2];
        pArr[pInd2] = Saved;
    }
}


解説

X座標の位置を指すポインタ配列
Y座標の位置を指すポインタ配列
を用意してます。

転置に関しては、転置回数が奇数なら
処理対象のX座標とY座標を入れ替えるようにしてます。