阿里妈妈4.3日笔试题
1.有一叠扑克牌,每张牌介于1和10之间
有四种出牌方法:
- 单出1张
- 出2张对子
- 出五张顺子,如12345
- 出三连对子,如112233
给10个数,表示1-10每种牌有几张,问最少要多少次能出完
回溯与搜索:
import java.util.*; public class AliBaba4_3_1 { private static int min_count=Integer.MAX_VALUE; //1-10数字的牌数 private static int[] poker=new int[10]; public static void main(String[] args) { Scanner scanner=new Scanner(System.in); int cnt=0; while(cnt<10){ poker[cnt]=scanner.nextInt(); cnt++; } //from:从哪个数字牌开始,count:已经出了多少次牌 backtrace(0,0); System.out.println(min_count); } //从from顺序出牌,count表示已经出了多少次牌,深搜 public static void backtrace(int from,int count){ //牌全出完了 if(from>=10){ min_count=Math.min(min_count,count); return; } //当前数字牌数为0,从下一数字牌开始 if(poker[from]==0){ backtrace(from+1,count); return; } //搜索出牌方案 //能出3连对 if(canContinuesTwo(from,3)){ takeIt(from,from+2,2); backtrace(from,count+1); returnBack(from,from+2,2); } //能出顺子 if(canContinuesOne(from,5)){ takeIt(from,from+4,1); //继续搜索 backtrace(from,count+1); //回溯 returnBack(from,from+4,1); } //能出连对 if(poker[from]>=2){ takeIt(from,from,2); //继续搜索 backtrace(from,count+1); //回溯 returnBack(from,from,2); } //出单张 takeIt(from,from,1); //继续搜索 backtrace(from,count+1); //回溯 returnBack(from,from,1); } public static boolean canContinuesOne(int from,int count){ if(from+count>=10)return false; for(int i=from;i<from+count;i++){ if(poker[i]<1)return false; } return true; } public static boolean canContinuesTwo(int from,int count){ if(from+count>=10)return false; for(int i=from;i<from+count;i++){ if(poker[i]<2)return false; } return true; } public static void takeIt(int from,int end,int count){ for(int i=from;i<=end;i++){ poker[i]-=count; } } public static void returnBack(int from,int end,int count){ for(int i=from;i<=end;i++){ poker[i]+=count; } } }
2.首先定义上升字符串s,s[i]≥s[i−1],比如aaa,abc是,acb不是
给n个上升字符串,选择任意个拼起来,问能拼出来的最长上升字符串长度
给n个上升字符串,选择任意个拼起来,问能拼出来的最长上升字符串长度
动态规划:
import java.util.*; public class AliBaba4_3_2 { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); int N=Integer.valueOf(scanner.nextLine()); System.out.println(N); //按照尾字母从小到大排序;如果相同则按照首字母从小到大排序 List<String>input=new ArrayList<>(); while(input.size()<N){ input.add(scanner.nextLine()); System.out.println(input.size()); } input.sort(new Comparator<String>() { @Override public int compare(String o1, String o2) { if(o1.charAt(o1.length()-1)==o2.charAt(o2.length()-1)) return o1.charAt(0)-o2.charAt(0); return o1.charAt(o1.length()-1)-o2.charAt(o2.length()-1); } }); //dp[i]表示以i+'a'字符结尾的最大连接长度 int dp[]=new int[26]; int max_len=0; for(int i=0;i<N;i++){ String s=input.get(i); char right=s.charAt(s.length()-1); char left=s.charAt(0); int max_temp=0; for(int j=0;j<=left-'a';j++){ //找出以某个字符(小于等于字符left)结尾的最大连接长度 max_temp=Math.max(max_temp,dp[j]); } dp[right-'a']=max_temp+s.length(); max_len=Math.max(max_len,dp[right-'a']); } System.out.println(max_len); } }输入:bcde aa aaa aab aaab bcf acdf 输出13