square869120Contest
次のsquare869120Contestの問題へ
前のsquare869120Contestの問題へ
square869120コンテスト2 B問題 Division 2
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("7 2");
WillReturn.Add("3");
WillReturn.Add("6");
//2
}
else if (InputPattern == "Input2") {
WillReturn.Add("7 2");
WillReturn.Add("6");
WillReturn.Add("3");
//3
}
else if (InputPattern == "Input3") {
WillReturn.Add("8 4");
WillReturn.Add("4");
WillReturn.Add("8");
WillReturn.Add("16");
WillReturn.Add("32");
//2
}
else if (InputPattern == "Input4") {
WillReturn.Add("50 4");
WillReturn.Add("8");
WillReturn.Add("6");
WillReturn.Add("4");
WillReturn.Add("3");
//9
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long mN;
static long[] mAArr;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
mN = wkArr[0];
var AList = new List<long>();
foreach (string EachStr in InputList.Skip(1)) {
string CurrStr = Regex.Replace(EachStr, "[^0-9]", "");
if (Regex.IsMatch(CurrStr, "^[0-9]+$")) {
AList.Add(long.Parse(CurrStr));
}
}
mAArr = AList.ToArray();
long[] ProdArr = ExecDFS();
foreach (long EachA in mAArr) {
for (long I = 0; I <= ProdArr.GetUpperBound(0); I++) {
if (ProdArr[I] % EachA == 0) {
ProdArr[I] /= EachA;
}
}
}
Console.WriteLine(ProdArr.Count(pX => pX == 1));
}
struct JyouaiDef
{
internal int CurrInd;
internal long CurrProd;
}
static long[] ExecDFS()
{
var WillReturn = new List<long>();
var Stk = new Stack<JyouaiDef>();
JyouaiDef WillPush;
WillPush.CurrInd = 0;
WillPush.CurrProd = 1;
Stk.Push(WillPush);
while (Stk.Count > 0) {
JyouaiDef Popped = Stk.Pop();
WillReturn.Add(Popped.CurrProd);
for (int I = Popped.CurrInd; I <= mAArr.GetUpperBound(0); I++) {
WillPush.CurrInd = I + 1;
if (WillOverProd(Popped.CurrProd, mAArr[I], mN)) {
continue;
}
WillPush.CurrProd = Popped.CurrProd * mAArr[I];
Stk.Push(WillPush);
}
}
return WillReturn.Distinct().ToArray();
}
// 2正数の掛け算が、Limitを超えるかを返す
static bool WillOverProd(long pA, long pB, long pLimit)
{
return pA > pLimit / pB;
}
}
解説
考察すると
割ったことで1になることの必要条件は、
aの配列の、1つ以上の要素の積であることだと分かります。
なので、
1つ以上の積をDFSで列挙してから
割れたら割る走査を、ナイーブにシュミレーションして、解くことができます。