第一次全做对惹,悄悄的骄傲一下下然后夹紧尾巴告诉自己是个弱鸡QAQ。
1.暴力
题目不记得了,大致意思就是给两个数组,一个数组a【i】表示在第i时刻能获得的知识,另一个数组b【i】只含1、0,1表示小明(名字是小明咩?)醒着,0表示他没醒,你有一次叫醒他的机会,可以叫醒k分钟,问他能得到的最多的知识是多少。emmm做了题的应该知道是哪一题吧,当时也没想太多,反正是暴力解,就不多说啦。
1 public static void main(String[] args) { 2 Scanner in = new Scanner(System.in); 3 while (in.hasNextInt()) {//注意while处理多个case 4 int n = in.nextInt(); 5 int k = in.nextInt();//叫醒的时间长度 6 int[] nums = new int[n]; 7 int[] alive = new int[n];//记录是否醒着的数组 8 int res = 0; 9 for(int i = 0;i<n;i++){ 10 nums[i] = in.nextInt(); 11 } 12 for(int i = 0;i<n;i++){ 13 alive[i] = in.nextInt(); 14 } 15 for(int i = 0;i<n;i++){ 16 if(alive[i] == 1){ 17 res += nums[i]; 18 } 19 } 20 int sum = 0,maxx = 0;//sum记录第i时刻叫醒能“多”获得的知识 21 for(int i = 0;i<n-k+1;i++){ 22 sum = 0; 23 for(int j = 0;j<k;j++){ 24 if(alive[i+j] == 0){ 25 sum += nums[i+j]; 26 } 27 } 28 maxx = Math.max(sum,maxx); 29 } 30 System.out.println(res+maxx); 31 } 32 }
代码有点乱,不过主要是为了做题,先ac了再去考虑别的啦。
2.苹果园(二分)
大意是给一个数组每个数表示第i堆苹果有几个,再给一个数k,问从左往右(从a【0】-a【n】)第k个苹果是哪一堆的。
用数组b【i】记录从a【0】-a【i】有多少个苹果,找到一个结果m,满足b【m】<k 且b【m+1】>k即可。二分查找,不然可能会超时。(看数据量猜的)。
交完卷,看到牛客讨论区说可以用红黑树,我才想到有treemap这种东西可以直接用,就不需要每次都写二分了,每次考虑边界都要卡好久QAQ。
1 public static void main(String[] args) { 2 Scanner in = new Scanner(System.in); 3 while (in.hasNextInt()) {//注意while处理多个case 4 int n = in.nextInt(); 5 int[] nums = new int[n]; 6 int last = 0; 7 for(int i = 0;i<n;i++){ 8 nums[i] = last+in.nextInt(); 9 last = nums[i]; 10 } 11 int m = in.nextInt(); 12 for(int i = 0;i<m;i++){ 13 int qi = in.nextInt(); 14 System.out.println(binarySearch(qi, nums)+1); 15 } 16 } 17 } 18 static int binarySearch(int n,int[] nums){//二分找 19 int l = 0; 20 int r = nums.length; 21 int mid = (l+r)/2; 22 while(l<r){ 23 mid = (l+r)/2; 24 if(mid == 0){ 25 return mid; 26 } 27 if(nums[mid-1] < n && nums[mid] >= n){ 28 return mid; 29 }else if(nums[mid] < n){ 30 l = mid+1; 31 }else { 32 r = mid; 33 } 34 } 35 return l; 36 }
3.字符串字典序
给n个'a'字符和m个‘z’字符,用全部字符组合成的字典序第k个(k为1就是最小的)的字符串是什么,比如2'a' 2'z' 第6个字典序为zzaa,如果不存在就输出-1。
看到题目感觉暴力肯定跑不完,就开始找规律,想找到一些规律,一开始思考是不是有z字符在第几位就可以加多少的规律,比如z在第一位就像二进制一样可以加1类似的规律,然后发现似乎没有;于是改变思路,突然发现自己写的代码一开始用到了计算n个a与m个z能组成的最多字符串数量,比较k,如果比k大,就存在,如果比k小,就输出-1,这个点提醒了我,可以试图把a放到最高位,然后计算n-1个a和m个z能组成的最多字符串数量,如果比k大,最高位就是z,如果比k小,最高位就是a,然后递归(当最高位是z时,要把k减去最高位为a时的数量)。突然醒悟!然后就ac啦!!(当然由于int会溢出,计算字符串总量时,ac前把max改成double就突然过了嘻嘻)
上代码:
1 public static void main(String[] args) { 2 Scanner in = new Scanner(System.in); 3 while (in.hasNextInt()) {//注意while处理多个case 4 int n = in.nextInt();//a 5 int m = in.nextInt();//z 6 int k = in.nextInt(); 7 double max = getMax(n, m);//计算最多的字符串数量 8 if(k>max){ 9 System.out.println(-1); 10 }else { 11 helper(n,m,k); 12 System.out.println(); 13 } 14 } 15 } 16 static void helper(int n,int m,int k){ 17 if(n == 0 && m == 0){ 18 return; 19 } 20 if(n == 0){//a个数为0时,就把z全输出 21 for(int i = 0;i<m;i++){ 22 System.out.print("z"); 23 } 24 return; 25 }else if (m == 0) { 26 for(int i = 0;i<n;i++){ 27 System.out.print("a"); 28 } 29 return; 30 } 31 double max = getMax(n-1, m); 32 if(max>=k){//如果比k大,就放a 33 System.out.print("a"); 34 helper(n-1, m, k); 35 }else {//如果比k小,就放z 36 System.out.print("z"); 37 helper(n, m-1, (int)Math.round(k-max)); 38 } 39 } 40 41 static double getMax(int n,int m){//计算n个a与m个z组成的字符串总量 42 double max = 1; 43 for(int i = 0;i<n;i++){ 44 max *= (m+n-i); 45 } 46 for(int i = 0;i<n;i++){ 47 max /= i+1; 48 } 49 return max; 50 }
emm,第一次ak,感觉运气很好,第三题恰好能发现那个规律(递归),不说了,滚去复习了(来自还没和面试官说过一句话的弱鸡)。