2022-5-23 笔试真题练习
作者:互联网
编程题]多多的求和计算
现在多多鸡想请你帮忙计算一下,满足和谐条件的区间的数量。
现在多多君想知道不同种类的骰子的数量分别有多少。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M
多多路上从左到右有N棵树(编号1~N),其中第i个颗树有和谐值Ai。 多多鸡认为,如果一段连续的树,它们的和谐值之和可以被M整除,那么这个区间整体看起来就是和谐的。现在多多鸡想请你帮忙计算一下,满足和谐条件的区间的数量。
输入描述:
第一行,有2个整数N和M,表示树的数量以及计算和谐值的参数。
( 1 <= N <= 100,000, 1 <= M <= 100 )
第二行,有N个整数Ai, 分别表示第i个颗树的和谐值。
( 0 <= Ai <= 1,000,000,000 )
输出描述:
共1行,每行1个整数,表示满足整体是和谐的区间的数量。
1 // dp[i][j] 以i结尾 2 import java.io.BufferedReader; 3 import java.io.IOException; 4 import java.io.InputStreamReader; 5 import java.util.*; 6 public class Main{ 7 public static void main(String[] args) throws IOException { 8 BufferedReader reader=new BufferedReader(new InputStreamReader(System.in)); 9 String s = reader.readLine(); 10 String arr=reader.readLine(); 11 String[] s1 = s.split(" "); 12 String[] s2=arr.split(" "); 13 int n=Integer.parseInt(s1[0]); 14 int m=Integer.parseInt(s1[1]); 15 int[] num=new int[n]; 16 int[][] dp=new int[n][m]; 17 for (int i=0;i<n;i++){ 18 num[i]=Integer.parseInt(s2[i]); 19 } 20 dp[0][num[0]%m]++; 21 int sum=dp[0][0]; 22 for (int i=1;i<n;i++){ 23 int mod=num[i]%m; 24 for (int j=0;j<m;j++){ 25 dp[i][(mod+j)%m]=dp[i-1][j]; 26 } 27 dp[i][mod]++; 28 sum+=dp[i][0]; 29 } 30 System.out.println(sum); 31 /** 32 * dp[i][j] 表示以i结尾 %m==j的数量 33 * dp[i+1][0~m-1]->dp[i]更新 34 * j+num[i+1] 35 */ 36 } 37 // 前缀和 sum[i] sum[j] 38 }
思路:用动态规划做卡9/10。想到了前缀和,没想到怎么处理。相同余数的前缀和可以组合成为一个区间,利用map记录个数再求和即可。
多多的骰子组合
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 256M,其他语言512M
多多君拼团购买了N个骰子,为了方便后面进行活动,多多君需要将这些骰子进行分类。 两个骰子为同类的定义是:1 |
将其中一个骰子通过若干次上下、左右或前后翻转后,其与另一个骰子对应的 6 面数字均相等。
|
输入描述:
第一行1个整数N,表示骰子的数量。(1 <= N <= 1,000)接下来N行,每行6个数字(1~6,且各不相同) 其中第i行表示第i个骰子当前上、下、左、右、前、后这6面的数字。
输出描述:
共2行:
第一行1个整数M,表示不同种类的骰子的个数
第二行M个整数,由大到小排序,表示每个种类的骰子的数量
1 // dp[i][j] 以i结尾 2 import java.io.BufferedReader; 3 import java.io.IOException; 4 import java.io.InputStreamReader; 5 import java.util.*; 6 public class Main{ 7 public static void main(String[] args){ 8 Scanner sc=new Scanner(System.in); 9 int n=sc.nextInt(); 10 int[][] arr=new int[n][6]; 11 for (int i=0;i<n;i++){ 12 for (int j=0;j<6;j++){ 13 arr[i][j]=sc.nextInt(); 14 } 15 } 16 17 // hash表记录对应的key 18 Map<String,Integer> map=new HashMap<>(); 19 // 记录当前筛子是否有了 20 HashSet<String> set=new HashSet<>(); 21 int[] count=new int[n]; 22 int num=-1; 23 for (int i=0;i<n;i++){ 24 25 String[] combine=getCombine(arr[i]); 26 for (String s:combine) System.out.println(s); 27 boolean f=false; 28 for (String s:combine){ 29 if (set.contains(s)){ 30 f=true; 31 break; 32 } 33 } 34 if (!f){ 35 // 没找到相同的筛子 36 num++; 37 for (String s:combine){ 38 set.add(s); 39 map.put(s,num); 40 } 41 count[num]++; 42 }else{ 43 count[map.get(combine[0])]++; 44 } 45 } 46 System.out.println(num+1); 47 Arrays.sort(count); 48 for (int i=n-1;i>=n-num-1;i--){ 49 System.out.print(count[i]+" "); 50 } 51 } 52 53 public static String[] getCombine(int[] arr){ 54 int index=0; 55 StringBuilder sb=new StringBuilder(); 56 for (int i=0;i<arr.length;i++){ 57 if (arr[i]==1) { 58 index=i; 59 } 60 } 61 62 63 64 if (index==3||index==5){ 65 66 //0 2 3 1 4 5 67 68 //0 2 3 4 5 1 69 swap(arr,0,index-1); 70 swap(arr,1,index); 71 swap(arr,0,1); 72 }else if (index==2||index==4){ 73 //0 2 1 3 4 5 74 //0 2 3 4 1 5 75 swap(arr,0,index); 76 swap(arr,1,index+1); 77 swap(arr,index,index+1); 78 }else if (index==1){ 79 //0 1 2 3 4 5 80 swap(arr,index-1,index); 81 swap(arr,2,3); 82 } 83 for (int x:arr) sb.append(x); 84 // 1在最前面的 85 String s=sb.toString(); 86 return new String[]{ 87 s,s.substring(0,2)+s.substring(4,6)+s.charAt(3)+s.charAt(2), 88 s.substring(0,2)+s.charAt(5)+s.charAt(4)+s.substring(2,4), 89 s.substring(0,2)+s.charAt(3)+s.charAt(2)+s.charAt(5)+s.charAt(4) 90 }; 91 92 } 93 94 public static void swap(int[] arr,int a,int b){ 95 int t=arr[a]; 96 arr[a]=arr[b]; 97 arr[b]=t; 98 } 99 }
思路:找到评判的标准来判断筛子。我的做法是对于任意的筛子肯定可以以1开头,前后固定,剩下4位可以通过旋转改变,一共有4种不同的结果,讲所有结果存入set中来判断是否相同,并在map中记录当前筛子的种类并计数。
标签:骰子,java,String,23,int,真题,2022,import,new 来源: https://www.cnblogs.com/benbicao/p/16302206.html