AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC154-B New Place
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("abab");
WillReturn.Add("abba");
//2
}
else if (InputPattern == "Input2") {
WillReturn.Add("3");
WillReturn.Add("arc");
WillReturn.Add("cra");
//2
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
string S = InputList[1];
string T = InputList[2];
int Result = Solve1(S, T);
Console.WriteLine(Result);
}
static int Solve1(string pS, string pT)
{
char[] SArr = pS.ToCharArray();
char[] TArr = pT.ToCharArray();
Array.Sort(SArr);
Array.Sort(TArr);
if (SArr.SequenceEqual(TArr) == false) {
return -1;
}
if (pS == pT) {
return 0;
}
int L = 0;
int R = TArr.Length - 1;
while (L + 1 < R) {
int Mid = (L + R) / 2;
string TailStr = pS.Substring(Mid);
if (IsSubSequence(TailStr, pT)) {
R = Mid;
}
else {
L = Mid;
}
}
return R;
}
// 文字列Substrが、文字列LongStrの(連続してなくてもよい)部分列かを判定
static bool IsSubSequence(string pSubstr, string pLongStr)
{
if (pSubstr == "") return true;
int IndS = 0;
int IndT = 0;
int UB_S = pSubstr.Length - 1;
int UB_T = pLongStr.Length - 1;
while (true) {
if (pSubstr[IndS] == pLongStr[IndT]) {
IndS++;
IndT++;
if (IndS > UB_S) return true;
if (IndT > UB_T) return false;
}
else {
IndT++;
if (IndT > UB_T) return false;
}
}
}
}
解説
まず、SとTの文字列のマルチセットとみて
集合が不一致なら不可です。
次に、Sがabcdefだとして考察します。
先頭3文字を移動させる場合は、
defに、abcを自由に入れれると考えることができます。
すると、先頭何文字を消せば、
残った文字列が、Tの(連続してなくてもよい)部分列かの判定にできるかの判定となり、
単調性があるので二分探索できます。