トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
AGC-013-A Sorted Arrays
■■■問題■■■
長さNの配列Aが与えられます。
Aを何箇所かで切って、Aの連続した部分であるようないくつかの数列に分けます。
この時、分けられたあとの数列は全て、
単調非減少または単調非増加な列になっている必要があります。
最小で何個の数列に分ければ良いかを求めて下さい。
■■■入力■■■
N
A1 A2 ・・・ AN
●1 <= N <= 10万
●1 <= Ai <= 10億
●Aiは全て整数である
■■■出力■■■
最小で何個の数列に分ければよいか出力せよ。
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "Input1";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("6");
WillReturn.Add("1 2 3 2 2 1");
//2
//[1,2,3] と [2,2,1] に分ければよいです
}
else if (InputPattern == "Input2") {
WillReturn.Add("9");
WillReturn.Add("1 2 1 2 1 2 1 2 1");
//5
}
else if (InputPattern == "Input3") {
WillReturn.Add("7");
WillReturn.Add("1 2 3 2 1 999999999 1000000000");
//3
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] AArr = InputList[1].Split(' ').Select(X => int.Parse(X)).ToArray();
int SuuretuCnt = 1;
int KouSuu = 0;
int PrevInt = -1;
bool CanZouka = true;
bool CanGensyou = true;
foreach (int EachA in AArr) {
bool WillCreateNewSuuretu = false;
KouSuu++;
if (KouSuu >= 2) {
//前の項より大きい場合
if (PrevInt < EachA) {
CanGensyou = false;
if (CanZouka == false) {
WillCreateNewSuuretu = true;
}
}
//前の項より小さい場合
if (PrevInt > EachA) {
CanZouka = false;
if (CanGensyou == false) {
WillCreateNewSuuretu = true;
}
}
}
if (WillCreateNewSuuretu) {
SuuretuCnt++;
CanZouka = CanGensyou = true;
KouSuu = 1;
}
PrevInt = EachA;
}
Console.WriteLine(SuuretuCnt);
}
}
解説
広義単調増加 → 広義単調減少 → 広義単調増加 → 広義単調減少 → 省略
と繰り返すか、
広義単調減少 → 広義単調増加 → 広義単調減少 → 広義単調増加 → 省略
と繰り返すのが最善ですので、
貪欲法を使ってます。