2019/04/05 腾讯笔试 后台及综合卷(java)
AC1.8(0.1+1.0+0.7),很菜,第三次筆試。
前兩次筆試(百度2019/04/02,拼多多2019/04/03)的時候,有些題目看完連反應都沒有,智商被按在地上摩擦,心態大崩。
痛定思痛,刷了兩天算法題,算是有點小小進步,至少今晚三道題目都有點感覺。
?
記錄一下,如果有人討論一下就更好了。
?
1.(AC0.1)給定n,m,是否能夠利用n種不同面值的硬幣組成1到m總值,如果可以輸出最少需要幾個硬幣,不可以輸出-1。
例如:n=4,m=20,n種面值硬幣:1,2,5,10? 輸出5
筆試時想法:
? ? ? 兩層嵌套循環,maxCount來統計至少需要多少數量的硬幣;從錢總值a? ?從1到m;數量c來統計錢總值a至少需要多少硬幣;硬幣的面值b從大到小進行遍歷,c=c+a/b,a=a%b,循環完判斷一下a是否為0,是則繼續循環,否則返回-1;如果c>maxCount,將maxCount=c。
? ? ? 漏洞:比如19=10*1+5*1+2*2(count=4)18=10*1+5*1+2*1+1*1(count=4),但是以19的面值組成成分沒法組成18,dead。
?
現在想法(剛考完):(目前還未發現有啥漏洞)
? ? ? 兩層嵌套循環,map1來統計各個面值硬幣一共需要多少個;從錢總值a? ?從1到m;map2來統計錢總值a,各個面值硬幣需要多少個;硬幣的面值b? 從大到小進行遍歷,map的面值b中放入a/b,a=a%b;更新map1,如果map2某個面值需要的數量大于map1則更新,map1為大的那個值,并且統計一下map1中全部加起來的總值sum,在后續遍歷中,如果錢總值a小于sum則直接跳過,不遍歷。最后,統計一下map1中所有面值需要的數量總和,輸出。
------------------------------------------------------2019/04/07更新---------------------------------------------------------
其實上面不用使用map,可以直接用數組來記錄,更新了一下代碼。
并為上面思路畫了一個草圖(一部分),方便大家理解,使用的栗子:以n=4,m=20,n種面值硬幣:1,2,5,10? 輸出5
? ? ?代碼:
import java.util.Arrays; import java.util.Scanner; public class Coin {public static void main(String[] args) {Scanner in = new Scanner(System.in);int m = in.nextInt();int n = in.nextInt();int[] ns = new int[n];for(int i=0;i<n;i++) ns[i] = in.nextInt();Arrays.sort(ns);//排序硬幣/*最小面值大于1,直接返回-1,因為1首先就沒法組合出來,其實只要有面值為1的硬幣,什么都可以組合出來*/if(ns[0]>1 ) {System.out.println(-1);return;}long[] result = new long[n];//result記錄總共各面值需要的數量int sum = 0;//result所有面值加起來的總和sumfor(int i=1;i<=m;i++) {if(i<=sum) continue;//錢總和 i 小于sum,就直接跳過int money = i;//當前要組成錢總值for(int j=n-1;j>=0;j--) {if(money/ns[j] != 0) {//當需要第j枚硬幣的數量大于result第j枚硬幣數量,則更新result中數量if(money/ns[j] > result[j]) result[j] = money/ns[j];money = money%ns[j];}if(money == 0) break;}//計算新的sumsum = 0;for(int k=0;k<n;k++) {sum += result[k]*ns[k];}}//統計總共需要多少個硬幣int count = 0;for (long c : result) count += c;System.out.println(count);} }?
2.(AC1.0)給定一個字符串,只有1和0,如果相鄰的兩個字符分別為1和0,則可以抵消,一直執行下去,問字符串最后剩下幾個字符。(送分題)
想法:
? ? ? ?統計字符串中0的數量A和1的數量B,返回A-B的絕對值。
(太簡單了,就不貼代碼了)
?
3.(AC0.7)你要穿過山谷,前面有n只怪獸,怪獸i你可以花費pi來收買它,它會護送你穿過山谷,如果遇到一個怪獸j,它的戰斗力是dj,護送你的全部怪獸加起來的戰斗力大于dj,你不需要收買它,否則你需要收買它才能通過。問你最少需要多少錢來穿過山谷。
? ? ?如,輸入n=4,d[]={1,2,4,8} p={1,2,1,2} 輸出 6
? ? ? ? ? ? 輸入n=3,d[]={8,5,10} p={1,1,2} 輸出2
筆試時想法:
? ? ? ?變量maxIndex來表示最大怪獸的下標,變量left表示要戰勝最大怪獸的戰斗值,怪獸從后往前遍歷,如果碰到怪獸的武力值大于left就更新maxIndex和left;收不收買當前的怪獸i取決于怪獸i之前的怪獸的戰斗力加起來是否大于d[maxIndex],大于等于則當前怪獸就可以不收買,小于收買,left=left-怪獸i武力值。
漏洞:好像沒有考慮到收買的錢,只考慮能不能打敗怪獸(●—●),具體怎么改還沒有想法
------------------------------------------------------2019/04/07更新---------------------------------------------------------
? ? ? ?看了牛客網很多帖子,正解應該是深度搜索+剪枝,但是題目的n是10^12,所以解空間很大,會花費很多時間。這里貼一個牛客網大佬AC的代碼,思路就是當怪獸i通過不了的時候就比較兩個條件①收買怪獸i的錢+當前已經花費的錢是否大于收買怪獸i之前全部怪獸的錢②怪獸i之前的全部怪獸的武力值總和是否大于怪獸i的武力值,兩個條件為true則收買怪獸i之前全部怪獸,否則收買怪獸i。
注明出處:
作者:永航? ? ?鏈接:https://www.nowcoder.com/discuss/173782?type=0&order=0&pos=6&page=1
?
代碼:
import java.util.Scanner;public class Third {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();long[] powers = new long[n];long[] moneys = new long[n];for (int i = 0; i < n; i++) {powers[i] = sc.nextLong();}for (int i = 0; i < n; i++) {moneys[i] = sc.nextLong();}long currPower = 0;long totalMoney = 0;for (int i = 0; i < n; i++) {if (currPower < powers[i]){if ((totalMoney+moneys[i]) > sum(moneys,0,i-1) &&powers[i] < sum(powers,0,i-1)){totalMoney = sum(moneys,0,i-1);currPower = sum(powers,0,i-1);continue;}totalMoney += moneys[i];currPower += powers[i];}else{continue;}}System.out.println(totalMoney);}private static long sum(long[] arr, int start, int end){long sum = 0;for (int i = start; i <= end; i++){sum += arr[i];}return sum;}?
2019/04/06? 0:17 記錄一下筆試時候的想法,希望后續通過自己或社區可以得到這三道題的AC1.0的解法。
2019/04/08? 0:26 更新了第一題幫助理解的草圖,第三題一個AC的代碼
總結
以上是生活随笔為你收集整理的2019/04/05 腾讯笔试 后台及综合卷(java)的全部內容,希望文章能夠幫你解決所遇到的問題。