51Nod 扔盘子

来源:互联网 发布:chart.js 编辑:程序博客网 时间:2024/05/01 10:25

有一口井,井的高度为N,每隔1个单位它的宽度有变化。现在从井口往下面扔圆盘,如果圆盘的宽度大于井在某个高度的宽度,则圆盘被卡住(恰好等于的话会下去)。
盘子有几种命运:1、掉到井底。2、被卡住。3、落到别的盘子上方。
盘子的高度也是单位高度。给定井的宽度和每个盘子的宽度,求最终落到井内的盘子数量。


如图井和盘子信息如下:
井:5 6 4 3 6 2 3
盘子:2 3 5 2 4

最终有4个盘子落在井内。
Input
第1行:2个数N, M中间用空格分隔,N为井的深度,M为盘子的数量(1 <= N, M <= 50000)。第2 - N + 1行,每行1个数,对应井的宽度Wi(1 <= Wi <= 10^9)。第N + 2 - N + M + 1行,每行1个数,对应盘子的宽度Di(1 <= Di <= 10^9)
Output
输出最终落到井内的盘子数量。
Input示例
7 5564362323524
Output示例
4
Java的运行时限为:3000 ms ,空间限制为:262144 KB

我的思路是盘子从上往下掉,那我就从上往下来比较井的尺寸和当前盘子的宽度,当卡住时,则记录卡住位置,设置为下次从上到下比较的结束点。一开始的结束点就是井底。

import java.io.PrintWriter;import java.util.Scanner;public class Node51_3_ThrowPlate {public long solve(int n,int m,long[] W,long[] D){int WPointer=0;//井int WEnd=n;//最靠近井口的被盘子挡住的井深度,最下面的话是被地面挡住int DPointer=0;//盘子while (WPointer < WEnd && DPointer < m) {while (WPointer < WEnd && W[WPointer] >= D[DPointer]) {WPointer++;}if(WPointer==0){return DPointer;}else{WPointer--;WEnd = WPointer;DPointer++;WPointer = 0;}}return DPointer;}public static void main(String[] args) {// TODO Auto-generated method stubScanner in = new Scanner(System.in);PrintWriter out = new PrintWriter(System.out);int n = in.nextInt();//井的深度int m = in.nextInt();//盘子的数量long[] W=new long[n];//井for(int i=0;i<n;i++){W[i]=in.nextLong();}long[] D=new long[m];//盘子for(int i=0;i<m;i++){D[i]=in.nextLong();}in.close();//4 3 3 8 7 10 1 5 2Node51_3_ThrowPlate node = new Node51_3_ThrowPlate();long b = node.solve(n,m,W,D);out.println(b);out.flush();}}
这样尽管结果正确,但是会TLE,我就去看了看大神的解法。
因为盘子如果能落到井的第n层,那么肯定能通过井的第1~n-1层,所以盘子能落到n层的条件就是盘宽<=min{井宽[0..i]} ,那么我们可以在Input井宽时,预处理使下层井宽小于或等于上层,这样的话就在开始时保证W[n]=min(W[1...n-1]),然后在盘子落下时直接从下往上找卡住的位置。
import java.io.PrintWriter;import java.util.Scanner;public class Node51_3_ThrowPlate_faster {public long solve(int n,int m,long[] W,long[] D){int WPointer=n-1;//井int DPointer=0;//盘子while (WPointer >=0 && DPointer < m) {while (WPointer >=0&&W[WPointer] < D[DPointer]) {WPointer--;}if(WPointer>=0){WPointer--;DPointer++;}}return DPointer;}public static void main(String[] args) {// TODO Auto-generated method stubScanner in = new Scanner(System.in);PrintWriter out = new PrintWriter(System.out);int n = in.nextInt();//井的深度int m = in.nextInt();//盘子的数量long[] W=new long[n];//井W[0]=in.nextLong();;for(int i=1;i<n;i++){W[i]=in.nextLong();W[i]=Math.min(W[i], W[i-1]);}long[] D=new long[m];//盘子for(int i=0;i<m;i++){D[i]=in.nextLong();}in.close();//4 1 7 9 3 9 9Node51_3_ThrowPlate_faster node = new Node51_3_ThrowPlate_faster();long b = node.solve(n,m,W,D);out.println(b);out.flush();}}
因为最多N个盘子,所以时间复杂度O(N)。比之前我的方法一遍遍地从上往下遍历井宽要快得多了。
原创粉丝点击