题目大意是这样的:有多组数据,每组开始给出 n 和 m (m, n ≤ 1000),n 代表价格标签的个数,m 代表要买的物品的个数,标签与物品种类一一对应。接下来一行有 n 个数,每个数代表一个价格。接着是 m 个物品名称,名称可重复出现,出现次数代表该物品购买数量。要求输出这些物品最低和最高的总价。
输入样例:
6 5 3 5 1 6 8 1 pear apple banana orange banana输出样例:
11 30对于样例,当 pear、apple、orange 和 banana 价格分别对应为 5、3、1、1 时,总价最低为11;价格分别对应为 3、5、6、8 时,总结最高为30。
因此,首先将物品数量降序排列,当价格升序时,将物品数量和价格从开始一一对应,得到的便是最低价;当价格降序时,将物品数量与价格一一对应,得到的便是最高价。
Java 代码如下:
import java.util.*; public class Main { public static void main(String args[]) { Scanner sc = new Scanner(System.in); int n, m; int[] val = new int[1000]; while (sc.hasNext()) { n = sc.nextInt(); m = sc.nextInt(); for (int i = 0; i < n; ++i) { val[i] = sc.nextInt(); } // 将物品存入 Map,Key 为物品名称,Value 为其个数 Map<String, Integer> mp = new <String, Integer>HashMap(); String name; for (int i = 0; i < m; ++i) { name = sc.next(); int num = mp.getOrDefault(name, 0) + 1; mp.put(name, num); } // 对价格升序排序 Arrays.sort(val, 0, n); List<Integer> list = new ArrayList<Integer>(mp.values()); int size = list.size(); Integer[] array = (Integer[])list.toArray(new Integer[size]); // 对物品数量升序排序 Arrays.sort(array); int max = 0, min = 0; int i = 0; for (Integer num : array) { max += val[n - size + i] * num; if (size - 1 - i >= 0) { min += num * val[size - 1 - i]; } i++; } System.out.println(min + " " + max); } } }如果一个数的二进制表示的每一位的和与其十进制表示的每一位的和相等,那么这个数就是幸运数。如十进制数123,12310 = 123,1232 = 01111011,两种表示每一位的和都是6,所以123就是一个幸运数。
输入时首先输入 t,代表数据的个数,接下来有t个数,对于每个数 n(n ≤ 1000000),输出从 1 到 n 中幸运数的个数。
输入样例:
3 1 21 22输出样例:
1 3 3开始我以为会有一定的规律,但是自己看了一会儿没有找到。接着想到的最快的方法就是使用一个数组保存已经计算的结果,如果后面输入的数小于等于之前的数,直接就能给出结果,就算大于之前的数,也可以利用之前计算的结果。
Java 代码如下:
import java.util.*; public class Main { static int f(int n) { int sum = 0; while (n != 0) { sum += n % 10; n /= 10; } return sum; } static int g(int n) { int sum = 0; while (n != 0) { sum += n & 1; n >>= 1; } return sum; } public static void main(String args[]) { Scanner sc = new Scanner(System.in); int t = sc.nextInt(); // 使用 buf 数组存储已经计算的结果 int[] buf = new int[1000010]; buf[1] = 1; // max 代表已经计算出的最大值 int max = 1; for (int i = 0; i < t; ++i) { int n = sc.nextInt(); if (n <= max) { System.out.println(buf[n]); } else { while (max < n) { ++max; // 利用前一个数的计算结果作为初始值 buf[max] = buf[max - 1]; if (g(max) == f(max)) { buf[max]++; } } System.out.println(buf[n]); } } } }