[问题描述]
小明公司的办公区有条长长的走廊, 由N个方格区域组成,如下图所示。
R R R 走廊内部署了K台打地机器人,其中第i台在第Ai个方格区域中。
己知扫地机器人每分钟可以移动到左右相邻的方格中,并将该区域清扫十净。
请你编写一个程序,计算每台机器人的清扫路线:使得
1.它们最终都返回出发方格,
2.每个方格区域都至少被清扫-遍,
3.从机器人开始行动到最后一台机器人归位花费的时间最少。
注意多台机器人可以同时清扫同一方块区域,它们不会互相影响。输出最少花费的时间。
在上图所示的例子中,最少花费时间是6。第一台路线: 2-1-2-3-4-3-2, 清扫了1、2、3、4号区域。
第二台路线5-6-7-6-5, 清扫了5 6、7.第三台珞线10-9-8-9-10,清扫了8、9和10.[输入格式]
第一行包含两个整数N和K。接下来K行,每行一个整数Ai。
输出格式:
输出一个整数,表示移动步数最多的机器人移动的步数
案例:
输入:
10 3
3 5 8
输出:
6
思路:先分几种情况讨论:
第一种情况:只有一个机器人
第二种情况:有两个机器人
第三种情况:有三个机器人
依次类推:然后找出共同点,然后优化代码,使其可以通过多个机器人。
第一段代码(最优)利用机器人的范围计算出时间。
第二段代码模拟来算出时间。
优化后的代码:
import java.util.Scanner;
public class Main {
public static int n,k;//n个格子的走廊 k个机器人
public static int [] a;//存k个机器人在a[]的位置
public static int count = Integer.MAX_VALUE;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
k = in.nextInt();
a = new int [k+1];
for (int i = 1; i <= k; i++) {//存k个机器人在a[]的位置
a[i] = in.nextInt();
}
System.out.println(dfs(1,0,0));
}
/**
* @param index 第index个机器人
* @param L 左边界
* @param aa 上一个机器人所花费的时间
* @return 扫完地花费时间最少的情况下,花费最多的那个机器人用了多长时间
*/
private static int dfs(int index,int L,int aa) {
if(index==k){
int aa1 = (n-L-1+1)*2-2;//最后一个机器人
aa = aa>aa1?aa:aa1;
count = count>aa?aa:count;
return count;
}
for(int i=a[index];i<a[index+1];i++){
int aa1 = (i-L-1+1)*2-2;//第index个机器人 i右边界
aa = aa>aa1?aa:aa1;
dfs(index+1,i,aa);
}
return count;
}
}
初始思路:代码贴出来供参考
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class test {
public static int n,k;//n个格子的走廊 k个机器人
public static int [] a,b;//存k个机器人在a[]的位置 b[]走廊 0未扫 1扫过
public static List c;//路径
public static int count = Integer.MAX_VALUE;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
k = in.nextInt();
a = new int [k+1];
b = new int [n+1];
c = new ArrayList();
for (int i = 1; i <= k; i++) {//存k个机器人在a[]的位置
a[i] = in.nextInt();
}
if(k==0){//如果没有机器人
System.out.println("0");
}else if(k==1){//如果只有一个机器人
dfs1(a[1],b,1,n,a[1]);
System.out.println(c.size());
}else if(k==2){//如果有两个机器人
for(int i=a[1];i<a[2];i++){//7 2 2 5
//第一个机器人的范围 1-2 1-3 1-4
//第二个机器人的范围3-7 4-7 5-7
// System.out.println("&:"+i+" "+n);
dfs1(a[1],b,1,i,a[1]);//第一个机器人
int aa1 = c.size();
c.clear();
for(int j=1;j<=n;j++){
b[j] = 0;
}
dfs1(a[2],b,i+1,n,a[2]);//第二个机器人
int aa2 = c.size();
// System.out.println(aa1+" "+aa2);
c.clear();
for(int j=1;j<=n;j++){
b[j] = 0;
}
aa1 = aa1>aa2?aa1:aa2;
count = count>aa1?aa1:count;
}
System.out.println(count);
}else if(k==3){//有三个机器人
for(int i=a[1];i<a[2];i++){//10 3 3 5 8
//第一个机器人的范围 1-3 1-4
// System.out.println("&:"+i+" "+n);
dfs1(a[1],b,1,i,a[1]);//第一个机器人
int aa1 = c.size();
c.clear();
for(int j=1;j<=n;j++){
b[j] = 0;
}
//第二个机器人的范围4-5 4-6 4-7
//第二个机器人的范围5 5-6 5-7
for(int j=a[2];j<a[3];j++){
dfs1(a[2],b,i+1,j,a[2]);//第二个机器人
int aa2 = c.size();
// System.out.println(aa1+" "+aa2);
c.clear();
for(int m=1;m<=n;m++){
b[m] = 0;
}
//第三个机器人的范围6-10 7-10 8-10
dfs1(a[3],b,j+1,n,a[3]);//第三个机器人
int aa3 = c.size();
c.clear();
for(int m=1;m<=n;m++){
b[m] = 0;
}
int aa = aa1>aa2?aa1:aa2;
aa = aa>aa3?aa:aa3;
count = count>aa?aa:count;
}
}
System.out.println(count);
}else{//三个机器人以上(递推出来的)
System.out.println(dfs(1,0,0));
}
}
/**
*
* @param index 第index个机器人
* @param L 左边界
* @param aa 上一个机器人所花费的时间
* @return 扫完地花费时间最少的情况下,花费最多的那个机器人用了多长时间
*/
private static int dfs(int index,int L,int aa) {
// System.out.println(k1+" "+index+" "+L+" "+aa);
if(index==k){
dfs1(a[index],b,L+1,n,a[index]);//最后一个机器人
int aa1 = c.size();
c.clear();
for(int j=1;j<=n;j++){
b[j] = 0;
}
aa = aa>aa1?aa:aa1;
count = count>aa?aa:count;
return count;
}
for(int i=a[index];i<a[index+1];i++){
dfs1(a[index],b,L+1,i,a[index]);//第index个机器人
int aa1 = c.size();
c.clear();
for(int j=1;j<=n;j++){
b[j] = 0;
}
aa = aa>aa1?aa:aa1;
dfs(index+1,i,aa);
}
return count;
}
/**
* 给出这个机器人的范围和它的位置,算出它扫完并且归位的最少时间
* @param a 机器人的位置
* @param b 自己范围的地扫完了没
* @param l 左边界
* @param r 右边界
* @param a1 原始位置
*/
private static void dfs1(int a,int [] b,int l,int r,int a1) {
if(a<l||a>r){//机器人越界
return;
}
boolean fal = true;
for(int i=l;i<=r;i++){//判断地扫完了没
if(b[i]==0){
fal = false;
break;
}
}
if(fal){//地扫完了
if(a == a1){//并且在最初的位置
// System.out.println(c+" "+c.size());
return;
}else{//没有在最初的位置
// b[a] = 1;
String cc = a+"";
c.add(cc);
if(a<a1){
dfs1(a+1,b,l,r,a1);
}else if(a>a1){
dfs1(a-1,b,l,r,a1);
}
}
return;
}
b[a] = 1;
String cc = a+"";
c.add(cc);
if(a-1<l){//左移越界
dfs1(a+1,b,l,r,a1);//右移
}else if(b[a-1]==0){//左边没扫
dfs1(a-1,b,l,r,a1);//左移
}else if(a+1>r){//右移越界
dfs1(a-1,b,l,r,a1);//左移
}else{//右移
dfs1(a+1,b,l,r,a1);
}
}
}