diff --git a/ykoiso/src/A066_Work.java b/ykoiso/src/A066_Work.java new file mode 100644 index 0000000000000000000000000000000000000000..f132d9e4135f37cdf98e761c0ed699b44230dedc --- /dev/null +++ b/ykoiso/src/A066_Work.java @@ -0,0 +1,101 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + +public class A066_Work { + static final int END = 0; + + public static void main(String[] args) { + Scanner scan = new Scanner(System.in); + // 仕事の開始日と終了日 + Map taskScheduleMap = new HashMap<>(); + // 各仕事の開始日 + List startDayList = new ArrayList<>(); + // 仕事の数 + final int taskNum = scan.nextInt(); + for (int i = 0; i < taskNum; i++) { + int startDay = scan.nextInt(); + int endDay = scan.nextInt(); + taskScheduleMap.put(startDay, endDay); + startDayList.add(startDay); + } + A066_Work work = new A066_Work(); + TaskDays taskDays = work.new TaskDays(startDayList, taskScheduleMap); + taskDays.makeConsecutiveDays(); + System.out.println(taskDays.getMostLongWorkDays()); + scan.close(); + } + + + class TaskDays { + private List startDayList; + private Map taskScheduleMap; + // 最大連勤日数 + private int mostLongWorkDays = 0; + + // コンストラクタ + TaskDays(final List startDayList, final Map taskScheduleMap) { + this.startDayList = startDayList; + this.taskScheduleMap = taskScheduleMap; + } + + // 出力用 + public int getMostLongWorkDays() { + return mostLongWorkDays; + } + + // 全てのタスクから最大連勤日数を計算する + public void makeConsecutiveDays() { + int startDay = 0, endDay = 0; + // 計算していない仕事が0になるまで + while (startDayList.size() > 0) { + // 開始日、終了日をリストの最初の仕事で設定 + startDay = startDayList.get(0); + endDay = taskScheduleMap.get(startDay); + // リストの最初の仕事を計算済みにする + startDayList.set(0, END); + // 連勤の計算 + calcConsecutiveDays(startDay, endDay); + // 計算済みの仕事を仕事リストから消去 + for (int i = startDayList.size() - 1; i >= 0; i--) { + if (startDayList.get(i) == END) { + startDayList.remove(i); + } + } + + } + } + + // 指定タスクの連勤計算 + public void calcConsecutiveDays(int startDay, int endDay) { + int nextStartDay = 0, nextEndDay = 0, workDays = 0; + for (int i = 1; i < startDayList.size(); i++) { + // 次の仕事の日程を読み込み + nextStartDay = startDayList.get(i); + nextEndDay = taskScheduleMap.get(nextStartDay); + // 連勤日数がつながっている場合 + if ((nextStartDay <= endDay + 1 && nextStartDay >= startDay - 1) + || (nextEndDay >= startDay - 1 && nextEndDay <= endDay + 1)) { + // 開始日と終了日を延ばせる場合更新 + if (startDayList.get(i) <= startDay) { + startDay = startDayList.get(i); + } + if (nextEndDay >= endDay) { + endDay = nextEndDay; + } + // 仕事を計算済みにする + startDayList.set(i, END); + } + } + // 連勤日数の計算 + workDays = endDay - startDay + 1; + if (workDays > mostLongWorkDays) { + mostLongWorkDays = workDays; + } + } + + } +} + diff --git a/ykoiso/test/A066_WorkTest.java b/ykoiso/test/A066_WorkTest.java new file mode 100644 index 0000000000000000000000000000000000000000..58f227ad466a1ed2becf646757544e0f61f98a81 --- /dev/null +++ b/ykoiso/test/A066_WorkTest.java @@ -0,0 +1,84 @@ +import static org.junit.Assert.assertThat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.*; + +public class A066_WorkTest { + A066_Work work = new A066_Work(); + A066_Work.TaskDays sut; + List startDayList; + Map taskScheduleMap; + + @Before + public void setUp() throws Exception { + taskScheduleMap = new HashMap<>(); + startDayList = new ArrayList<>(); + taskScheduleMap.clear(); + startDayList.clear(); + } + + @Test + public void 連勤であることを判断できる() { + startDayList.add(5); + startDayList.add(13); + taskScheduleMap.put(5, 12); + taskScheduleMap.put(13, 15); + System.out.println(startDayList); + System.out.println(taskScheduleMap); + sut = work.new TaskDays(startDayList, taskScheduleMap); + sut.makeConsecutiveDays(); + int actual = sut.getMostLongWorkDays(); + int expected = 15 - 5 + 1; + assertThat(actual, is(expected)); + } + + @Test + public void 連勤でないことを判断できる() { + startDayList.add(5); + startDayList.add(13); + taskScheduleMap.put(5, 11); + taskScheduleMap.put(13, 15); + sut = work.new TaskDays(startDayList, taskScheduleMap); + sut.makeConsecutiveDays(); + int actual = sut.getMostLongWorkDays(); + int expected = 11 - 5 + 1; + assertThat(actual, is(expected)); + } + + @Test + public void 期間がかぶっている連勤を判断できる() { + startDayList.add(5); + startDayList.add(6); + taskScheduleMap.put(6, 8); + taskScheduleMap.put(5, 12); + System.out.println(startDayList); + System.out.println(taskScheduleMap); + sut = work.new TaskDays(startDayList, taskScheduleMap); + sut.makeConsecutiveDays(); + int actual = sut.getMostLongWorkDays(); + int expected = 12 - 5 + 1; + assertThat(actual, is(expected)); + } + + @Test + public void タスクが3つ以上の連勤を判断できる() { + startDayList.add(5); + startDayList.add(13); + startDayList.add(1); + taskScheduleMap.put(1, 8); + taskScheduleMap.put(5, 12); + taskScheduleMap.put(13, 15); + System.out.println(startDayList); + System.out.println(taskScheduleMap); + sut = work.new TaskDays(startDayList, taskScheduleMap); + sut.makeConsecutiveDays(); + int actual = sut.getMostLongWorkDays(); + int expected = 15 - 1 + 1; + assertThat(actual, is(expected)); + } +}