题目描述
某餐馆有n张桌子,每张桌子有一个参数:a 可容纳的最大人数; 有m批客人,每批客人有两个参数:b人数,c预计消费金额。 在不允许拼桌的情况下,请实现一个算法选择其中一部分客人,使得总预计消费金额最大
输入描述:
输入包括m+2行。 第一行两个整数n(1 <= n <= 50000),m(1 <= m <= 50000) 第二行为n个参数a,即每个桌子可容纳的最大人数,以空格分隔,范围均在32位int范围内。 接下来m行,每行两个参数b,c。分别表示第i批客人的人数和预计消费金额,以空格分隔,范围均在32位int范围内。
输出描述:
输出一个整数,表示最大的总预计消费金额
示例1
输入
3 5 2 4 2 1 3 3 5 3 7 5 9 1 10
输出
20
1 import java.util.*; 2 public class Main { 3 public static void main(String[] args) { 4 Scanner sc=new Scanner(System.in); 5 int count=sc.nextInt(); 6 int guest=sc.nextInt(); 7 int[] gust_count=new int[guest]; 8 int[] gust_pr=new int[guest]; 9 int[] desk_Cap=new int[count]; 10 for (int i = 0; i < count; i++) { 11 desk_Cap[i]=sc.nextInt(); 12 } 13 Arrays.sort(desk_Cap); 14 boolean[] isUsed = new boolean[count];//默认为false 15 //使用优先队列来存储选择顾客组的顺序 先进先出 16 Queue<Pval> Set = new PriorityQueue<Pval>(); 17 for (int i = 0; i < guest; i++) { 18 gust_count[i]=sc.nextInt(); 19 gust_pr[i]=sc.nextInt(); 20 Set.add(new Pval(gust_count[i],gust_pr[i])); 21 } 22 sc.close(); 23 24 25 26 long sum=0;//int类型的数据相加可能超出范围 27 28 while(!Set.isEmpty()) { 29 Pval p=Set.poll(); 30 for (int i = 0; i < desk_Cap.length; i++) { 31 if (desk_Cap[i]>=p.people&!isUsed[i]) {//isUsed数组用来记录该桌子是否被占用 32 sum=sum+p.value; 33 isUsed[i]=true; 34 break; 35 } 36 } 37 } 38 System.out.println(sum); 39 } 40 /将两个元素转化为可以比较的对象先将消费金额大的加入到队列当消费金额相同时先考虑人比较少的情况因为事先已经对桌子的容量客人数即第二行已经排序了 节省时间 41 static class Pval implements Comparable<Pval>{ 42 int people; 43 int value; 44 public Pval(int people, int value) { 45 super(); 46 this.people = people; 47 this.value = value; 48 } 49 @Override 50 public int compareTo(Pval t) { 51 if(this.value == t.value) 52 { 53 return this.people < t.people ? -1 : 1; 54 } 55 else 56 { 57 return this.value > t.value ? -1 : 1; 58 } 59 60 } 61 62 63 } 64 }
题目描述
输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2
1 import java.util.*;
2 public class Main {
3 public static void main(String[] args) {
4 Scanner sc=new Scanner(System.in);
5 int data=sc.nextInt();
6 int count=0;//分解质因数5注意25 125
7 while (data/5!=0) {
8 data=data/5;
9 count=count+data;
10 };
11 System.out.println(count);
12 }
13
14 }
题目描述:连续最大和
一个数组有 N 个元素,求连续子数组的最大和。 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3
输入描述:
输入为两行。 第一行一个整数n(1 <= n <= 100000),表示一共有n个元素 第二行为n个数,即每个元素,每个整数都在32位int范围内。以空格分隔。
输出描述:
所有连续子数组中和最大的值。
输入例子1:
3 -1 2 1
输出例子1:
3
import java.util.*; public class Main { public static int getMaxSum(int[] a) { int sum[]=new int[a.length]; sum[0]=a[0]; int count=0; for (int i = 0; i < a.length; i++) { if(a[i]<0) count++; } if(count==a.length) { return a[0];//排除全是负值的情况 } if(a[0]<0) sum[0]=0;//排除首个是-1的情况 for (int i = 1; i < a.length; i++) { sum[i]=(sum[i-1]+a[i])>0?(sum[i-1]+a[i]):0; } Arrays.sort(sum); return sum[a.length-1]; } public static void main(String[] args) { Scanner sc=new Scanner(System.in); int count=sc.nextInt(); int data[] =new int[count]; for(int i=0;i<count;i++) { data[i]=sc.nextInt(); } System.out.println(getMaxSum(data)); } }
[编程题] 进制转换
给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数
输入描述:
输入为一行,M(32位整数)、N(2 ≤ N ≤ 16),以空格隔开。
输出描述:
为每个测试实例输出转换后的数,每个输出占一行。如果N大于9,则对应的数字规则参考16进制(比如,10用A表示,等等)
输入例子1:
7 2
输出例子1:
111
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int data=sc.nextInt(); int jz=sc.nextInt(); Stack<Object> stack=new Stack<>(); int tempd=0; if (data<0) {//考虑负数的情况 tempd=data; data=-data; } while(data!=0) { int temp=data%jz; if (temp>=10||temp<=15) { String temp1=Integer.toHexString(temp).toUpperCase(); stack.push(temp1); } else { stack.push(temp); } data=data/jz; } String s=""; while(!stack.isEmpty()) { s=s+stack.pop(); } if (tempd<0) { System.out.println("-"+s); }else { System.out.println(s); } } }
题目描述
给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。
输入描述:
输入为两行:
第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
第二行为n个正整数A[i](32位整数),以空格隔开。
输出描述:
输出所求的方案数
输入:
5 15
5 5 10 2 3
输出:
4
(1)首先构造初始值,即第一排和第一行
(2)对于从第一行第一列开始则若该行的data[i]即输入数据小于或等于j(构造出来的中间和)ar[i]要考虑ar[i-1][j]与arr[i-1][j-data[i]]之和,例如ar[3]10]=2+a[2][10-7]否则只考虑ar[i-1][j]即可
状态转移方程:
1 import java.util.*; 2 public class Main { 3 public static void main(String[] args) { 4 Scanner sc=new Scanner(System.in); 5 int count=sc.nextInt(); 6 int sum=sc.nextInt(); 7 int[] data=new int[count+1]; 8 data[0]=0; 9 for (int i = 1; i < count+1; i++) { 10 data[i]=sc.nextInt(); 11 } 12 long[][] ar=new long[count+1][sum+1];//int类型求和用long存储 13 for (int i = 0; i < ar[0].length; i++) { 14 ar[0][i]=0; 15 } 16 for (int i = 0; i < ar.length; i++) { 17 ar[i][0]=1; 18 } 19 for (int i = 1; i < ar.length; i++) { 20 for (int j = 1; j < ar[0].length; j++) { 21 if (data[i]<=j) { 22 ar[i][j]=ar[i-1][j]+ar[i-1][j-data[i]]; 23 24 }else { 25 ar[i][j]=ar[i-1][j];//确定初始值状态转移方程 26 } 27 } 28 } 29 System.out.println(ar[ar.length-1][ar[0].length-1]); 30 31 } 32 33 }
题目描述:
给你六种面额1、5、10、20、50、100元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N为0-10000的非负整数)的不同组合的个数。
输入描述:
输入为一个数字N,即需要拼凑的面额
输出描述:
输出也是一个数字,为组成N的组合个数。
示例1
输入
5
输出
2
package uestc; import java.time.zone.ZoneRulesProvider; import java.util.HashSet; import java.util.Hashtable; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); int money=scanner.nextInt(); System.out.println(countWays(money)); } public static int countWays(int money) { int[] data=new int[]{1,5,10,20,50,100}; int[][] data_1=new int[6][money+1]; for (int i = 0; i < data_1.length; i++) { data_1[i][0]=1; } for (int i = 0; i < data_1[0].length; i++) { data_1[0][i]=1; } for (int i = 1; i <data_1.length; i++) { for (int j = 1; j <data_1[i].length; j++) { if (j>=data[i]) { data_1[i][j]=data_1[i-1][j]+data_1[i][j-data[i]]; } else { data_1[i][j]=data_1[i-1][j]; } } } // for (int i = 0; i < data_1.length; i++) { // for (int j = 0; j < data_1[i].length; j++) { // System.out.print(data_1[i][j]+" "); // } // System.out.println(); // } return data_1[5][money]; } }