第十届蓝桥杯——扫地机器人 java

[问题描述]

      小明公司的办公区有条长长的走廊, 由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);
		}
	}

}

 

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萤火的微亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值