AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC136-B Triple Shift
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("4");
WillReturn.Add("3 1 4 5");
WillReturn.Add("4 1 5 3");
//Yes
}
else if (InputPattern == "Input2") {
WillReturn.Add("3");
WillReturn.Add("1 2 2");
WillReturn.Add("2 1 2");
//Yes
}
else if (InputPattern == "Input3") {
WillReturn.Add("3");
WillReturn.Add("1 2 3");
WillReturn.Add("2 3 4");
//No
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int[] mAArr;
static int[] mBArr;
static void Main()
{
List<string> InputList = GetInputList();
mAArr = InputList[1].Split(' ').Select(pX => int.Parse(pX)).ToArray();
mBArr = InputList[2].Split(' ').Select(pX => int.Parse(pX)).ToArray();
if (IsSameMultiSet() == false) {
Console.WriteLine("No");
return;
}
if (mAArr.Length > mAArr.Distinct().Count()) {
Console.WriteLine("Yes");
return;
}
for (int I = 0; I <= mAArr.GetUpperBound(0) - 2; I++) {
if (mAArr[I] == mBArr[I]) continue;
int BaseInd = Array.IndexOf(mAArr, mBArr[I]);
while (mAArr[I] != mBArr[I]) {
BaseInd = Math.Max(BaseInd - 2, I);
ExecRotate(BaseInd);
}
}
if (mAArr.SequenceEqual(mBArr)) {
Console.WriteLine("Yes");
}
else {
Console.WriteLine("No");
}
}
// 添字を引数として、3つの要素をローテートする
static void ExecRotate(int pBaseInd)
{
int Val1 = mAArr[pBaseInd];
int Val2 = mAArr[pBaseInd + 1];
int Val3 = mAArr[pBaseInd + 2];
mAArr[pBaseInd] = Val3;
mAArr[pBaseInd + 1] = Val1;
mAArr[pBaseInd + 2] = Val2;
}
// マルチセットとして見て集合が一致するかを返す
static bool IsSameMultiSet()
{
int[] SotredArr1 = mAArr.OrderBy(pX => pX).ToArray();
int[] SotredArr2 = mBArr.OrderBy(pX => pX).ToArray();
return SotredArr1.SequenceEqual(SotredArr2);
}
}
解説
必要条件として、
マルチセットとして見て、不一致ならNGになります。
この必要条件を満たせば
十分条件として、Aが重複した要素を持てば、
重複した要素で調整できるのでOKになります。
最後に、数列の左端から順に合わせていって、
数列を一致させれるかを判定してます。