トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
No.52 よくある文字列の問題
■■■問題■■■
文字列Sが与えられる。
文字列Sの「先頭」または「末尾」から1文字ずつ文字をとってきて、
取った文字列とは別に、取った文字を順番につなげて新たに文字列を作る。
Sは、文字を取った後の文字列を新たなSとしてSの文字列がなくなるまで繰り返す。
この時、新たにできる文字列は何通りの文字列ができるか?
■■■入力■■■
S
Sは小文字のaからzのアルファベットからなる最短1文字最長10文字の文字列
■■■出力■■■
できる文字列の数Ansを出力せよ。
最後に改行を忘れないように。
C#のソース
using System;
using System.Collections.Generic;
class Program
{
static string InputPattern = "Input1";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("abc");
//4
//abc、acb、cab、cbaの4通りがある
}
else if (InputPattern == "Input2") {
WillReturn.Add("aab");
//3
//aab、aba、baaの3通りがある
}
else if (InputPattern == "Input3") {
WillReturn.Add("aaaaaaaaaa");
//1
//どのようにしてもaaaaaaaaaaにしかならない
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct JyoutaiDef
{
internal string CurrStr;
internal string CreateStr;
}
static void Main()
{
List<string> InputList = GetInputList();
string S = InputList[0];
var stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.CurrStr = S;
WillPush.CreateStr = "";
stk.Push(WillPush);
var CreateStrSet = new HashSet<string>();
while (stk.Count > 0) {
JyoutaiDef Popped = stk.Pop();
//クリア判定
if (Popped.CurrStr == "") {
CreateStrSet.Add(Popped.CreateStr);
continue;
}
Action<int> PushSyori = pRemoveInd =>
{
WillPush.CurrStr = Popped.CurrStr.Remove(pRemoveInd, 1);
WillPush.CreateStr = Popped.CreateStr + Popped.CurrStr[pRemoveInd];
stk.Push(WillPush);
};
PushSyori(0);
PushSyori(Popped.CurrStr.Length - 1);
}
Console.WriteLine(CreateStrSet.Count);
}
}
解説
深さ優先探索で全探索してます。