枚举和暴力

    技术2022-07-12  74

    铺地毯

    为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有n张地毯,编号从1到n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。 输入 第一行,一个整数n,表示总共有n张地毯。 接下来的n行中,第i+1行表示编号i的地毯的信息,包含四个正整数a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标(a,b)以及地毯在x轴和y轴方向的长度。 第n+2行包含两个正整数x和y,表示所求的地面的点的坐标(x,y)。 输出 输出共1行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出-1。 思路:这个题目其实很简单,就是判断输入的点是否在给的长方形内,并且找到最上面覆盖那个。 开始我的思路是从第一个开始循环,如果找到一个就++,但是提交后错误,后来发现问题所在之处就是在比如这个点是被1和3覆盖,如果找到就加加,那么输出就是2,并不是最上面的序号3.所以不能用加加,应该直接赋值,符合一个就把序号赋值。 写完后发现,如果这样从头开始找那么每个都会遍历一遍,倒不如从最末尾开始找,因为是要找最上面那一个,找到就break即可。

    import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n=scanner.nextInt(),flag=-1; int[][] size=new int[n][4]; for (int i=0;i<size.length;i++){ for (int j=0;j<size[i].length;j++){ size[i][j]=scanner.nextInt(); } } int x=scanner.nextInt(),y=scanner.nextInt(); for (int i=n-1;i>=0;--i){ if(x>=size[i][0] && x<=(size[i][0]+size[i][2]) && y>=size[i][1] && y<=(size[i][1]+size[i][3])){ flag=i+1; break; } } System.out.println(flag); } }

    校门外的树

    链接:https://ac.nowcoder.com/acm/problem/16649 来源:牛客网

    某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

    由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。 链接:https://ac.nowcoder.com/acm/problem/16649 来源:牛客网

    输入描述: 第一行有两个整数:L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。 输出描述: 包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

    示例1 输入 复制 500 3 150 300 100 200 470 471 输出 复制 298 思路:还是区间覆盖的贪心,首先想到的是防止tle,使用离散化。但是有种更简便的方法就是定义另一个数组,循环判断这个位置上是否有树,如果有则为false。最后循环这个数组,计数没有树的位置。 但是我想的方法是先把每个区间的左端点按升序排列,然后将前一个的终止点和后一个的起始点作比较。 如果终止点小于后一个起始点,则算出差值。再在这两个区间中找到最大终止点并进行赋值,再和下一个起始点进行比较。

    import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int L=scanner.nextInt(),M=scanner.nextInt(); int[][] nums=new int[M][2]; for(int i=0;i<nums.length;i++){ for(int j=0;j<nums[i].length;j++){ nums[i][j]=scanner.nextInt(); } } /*应该按照起始点排序*/ Arrays.sort(nums,new Comparator<int[]>(){ public int compare(int[] a,int[] b){ if(a[0]==b[0]){ return a[1]-b[1]; }else{ return a[0]-b[0]; } } }); int tree=nums[0][0],endTree=nums[0][1]; for (int i=1;i<M;i++){ if(endTree<nums[i][0]){ tree+=nums[i][0]-endTree-1; } endTree=Math.max(nums[i][1],endTree); } tree+=L-endTree; System.out.println(tree); } }

    需要注意的几点:1. 排序–如果按照左端点升序排序,那么初始值是正确的。但是如果按照右端点升序排序,则tree的初始值错误。

    比如:[0,50], [10,20],[60,61] 按右端点升序:[10,20],[0,50],[60,61],这样tree的初始值就是10,但正确答案是0

    tree的初始值–开始的时候我把tree的初始值设为排序之后,第一个区间到起点的距离+最后一个区间到终点的距离。一开始的思维被固定住,导致后来找错误时一直没往这里想。但是根据左端点进行排序的之后,最后一个的终止点并不是最大,所以初始值不能这样写。

    比如:[0,50], [10,20],[30,31] 按右端点升序:[0,50],[10,20],[30,31],这样tree的初始值就是0+(终止点-31),但正确答案是(终止点-50)

    再将endTree和后一个起始点作比较之后,不管是大还是小或者等于,都要将endTree进行重新赋值,将endTree和下一个区间的起始点作比较,较大的那一个赋值。

    一开始我是只在endTree小于下一区间起始点时,进行计算并且赋值 但比如:[10,20] [15,30],[22,40],这两个区间,不进行重新赋值,那么endTree第一次还是为20,这样就会有一个22-20+1的计算,这是错误的。

    拼数

    设有n个正整数(n ≤ 20),将它们联接成一排,组成一个最大的多位整数。 例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213 又如:n=4时,4个整数7,13,4,246联接成的最大整数为:7424613 这一题有个坑的地方就是如果按照正常思路的话肯定是先排序,大的数在前面,但是这样就会出现一个问题,

    41 4004 40 正确:41404004 排序后:4004 41 40错误的 所以先将其转换成字符串,再比较大小,这样是按照字典序排序:41 4004 40 错误的,因为字典序4004>40 所以先拼接再比较排序 即AB>BA,则B在A前面。 400440<4040004 所以排序:41 40 4004

    import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n=scanner.nextInt(); String[] nums=new String[n]; for (int i=0;i<nums.length;i++){ nums[i]=scanner.next(); } //重点在这里,对字符串排序 Arrays.sort(nums, new Comparator<String>() { @Override public int compare(String o1, String o2) { //先 contant-》拼接,再比较AB.compareTo.BA,如果小于0,则AB较小 if(o1.concat(o2).compareTo(o2.concat(o1))<0){ return 1; //return 1,即o2在前。 }else { return -1; } } }); for (int i=0;i<nums.length;i++){ System.out.print(nums[i]); } } }
    Processed: 0.011, SQL: 10