釣魚 - 演算法(暫存)
阿新 • • 發佈:2018-11-30
- 釣魚題
總共N個座位,三個門,每個門後面有M個人。進入的規則:門的順序可以變,但是每個門開啟後,門後的人必須全部進去才能開下一個門。每個人只能坐在離他最近的座位上,求人全部進入所走的最小步數
5 –test case
10 –總共的座位數
4 5 – 第一個門的位置是4,有5個人
6 2 – 第二個門的位置是6,有2個人
10 2 – 地三個門的位置是10,有2個人
10 – 下一組case
8 5
9 1
10 2
24
15 3
20 4
23 7
39
17 8
30 5
31 9
60
57 12
31 19
38 16
1 18
2 25
3 57
4 86
5 339
package com.daxiong.fish;
import java.io.*;
import java.util.*;
public class Fish {
static int[] data;
static int sit;
static int[] door;
static int minSteps;
static int[] orgin;
static int[] allPer;
static int[] used;
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(new File("src/case/fish.txt"));
int door_one,door_sec,door_thr;
int exit = sc.nextInt();
while ((exit--) != 0) {
sit = sc.nextInt();
data = new int[sit + 10];
door = new int[sit + 10];
door_one = sc.nextInt();
door[door_one] = sc.nextInt();
door_sec = sc.nextInt();
door[door_sec] = sc.nextInt();
door_thr = sc.nextInt();
door[door_thr] = sc.nextInt();
minSteps = 1000;
allPer = new int[100];
used = new int[3];
orgin = new int[3];
orgin[0] = door_one;
orgin[1] = door_sec;
orgin[2] = door_thr;
allPer(0);
System.out.println(".....");
}
}
// 1 2 3 4 5 6 7 8 9 10
// 5 2 2
// 1 2 3 2 3 2 3 1 2 =
static void bfs(int[] curData, int doorIndex, int curIndex, int num,int sumStep) {
System.out.println(doorIndex + "," + sumStep);
if (num == 0) { // 下一個門
if(door[curData[doorIndex+1]] > 0){
bfs(curData, doorIndex + 1, curIndex, door[curData[doorIndex+1]],sumStep);
}
if (doorIndex == 2) { // 3 個門 結束
minSteps = sumStep < minSteps ? sumStep : minSteps;
}
return;
}
int i = 0,j = 0,before = 0,after = 0;
boolean isLeft = false,isRight = false;
for (i = curData[doorIndex]; i > 0; i--) { // 遍歷左邊
if (data[i] != 1) {
before = curData[doorIndex] - i;
isLeft = true;
break;
}
}
for (j = curData[doorIndex]; j <= sit; j++) { // 右邊
if (data[j] != 1) {
after = j - curData[doorIndex];
isRight = true;
break;
}
}
// 如果左邊或者右邊沒有了
if(!isLeft){ // 左邊沒有,放右邊
data[j] = 1;
bfs(curData, doorIndex, curIndex, num - 1,sumStep + after + 1);
}
if(!isRight){ // 右邊沒有了,放左邊
data[i] = 1;
bfs(curData, doorIndex, curIndex, num - 1,sumStep + before + 1);
}
if (after >= 0 && after <= sit && before >= 0 && before <= sit) {
// 判斷距離
if ((before == after)) {
if (after == 0) { // 當前點
data[i] = 1;
bfs(curData, doorIndex, curIndex, num - 1,sumStep + 1);
} else { // 不同的兩點
if(num-2 >= 0){
data[i] = data[j] = 1;
bfs(curData, doorIndex, curIndex, num - 2,sumStep + before + after + 2);
} else {
data[i] = 1; // 先放左邊
bfs(curData, doorIndex, curIndex, num - 1,sumStep + before + 1);
}
}
} else if (before < after) { // 放到左邊
data[i] = 1;
bfs(curData, doorIndex, curIndex, num - 1,sumStep + before + 1);
} else { // 右邊
data[j] = 1;
bfs(curData, doorIndex, curIndex, num - 1,sumStep + after + 1);
}
}
}
// 全排列
static void allPer(int index){
if(index == 3){
minSteps = 1000;
for(int i = 0;i < (sit + 10);i++){
data[i] = 0;
}
bfs(allPer, 0, 0, door[allPer[0]],0);
System.out.println(minSteps);
return;
}
for(int i = 0;i < 3;i++){
if(used[i] != 1){
used[i] = 1;
allPer[index] = orgin[i];
allPer(index+1);
used[i] = 0;
}
}
}
static void print() {
System.out.println("--------------");
for (int i = 1; i <= sit; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
System.out.println("--------------");
}
}