Topcoder_157
来源:互联网 发布:微软的云计算系统 编辑:程序博客网 时间:2024/06/16 16:07
【问题描述】
有n张卡片,每张卡片有一些整数值,并且在这些卡片上也标注了一些字母。同时,在你面前有一排n个插槽,每个插槽上标注了数字。
现在你需要做的是将此n张卡片放入这n个插槽(每个插槽1张),并且要达到卡片上的数值不小于插槽上标注的数字。最终的结果就是你要给出从左到右排列的字母(代表卡片),并且在满足前面条件的基础上,结果的字母排列尽量按照字母顺序。
题目中给定一个int数组和一个字符串,字符串的第i个元素和int数组的第i个元素就是第i张卡片上的标识。同时另外给定的一个int数组就是n个插槽的标注值。插槽的顺序是从左向右。返回的字符串就是卡片的排列顺序,如果不存在解,那么返回一个空字符串。
定义:
类 CardsAndSlots
方法 public String firstValid(int[] values, String letters, int[] required)
约束:
1、卡片数量在1至50之间(包括)
2、每个卡片的值和插槽的值在1至1000之间(包括)
3、给定的字符串letters的长度、values数组的长度、required数组的长度相同
4、给定的字符串letters仅包含大写英文字母('A'-'Z')
例子:
1、values {1, 2, 3};letters "ABC";required {2, 2, 1}
Returns: "BCA"
2、values {1, 2, 3, 4, 5};letters "BBBAA";required {1, 1, 1, 1, 5}
Returns: "ABBBA"
3、values {1, 1};letters "AA";required {2, 2}
Returns: ""
【我的解答】
【思想】
使用循环检测的方法,即每次选择最小的字母然后检测在这个位置使用这个字母,是否会得到解,如果可以得到解就记录。
此处用到了以下事实,将values和required数组中现在可用的值(未被使用)排序,如果存在某一位置上的values的值小于required的值,那么无论怎么调整至少存在一个位置values的值将小于required的值。
有n张卡片,每张卡片有一些整数值,并且在这些卡片上也标注了一些字母。同时,在你面前有一排n个插槽,每个插槽上标注了数字。
现在你需要做的是将此n张卡片放入这n个插槽(每个插槽1张),并且要达到卡片上的数值不小于插槽上标注的数字。最终的结果就是你要给出从左到右排列的字母(代表卡片),并且在满足前面条件的基础上,结果的字母排列尽量按照字母顺序。
题目中给定一个int数组和一个字符串,字符串的第i个元素和int数组的第i个元素就是第i张卡片上的标识。同时另外给定的一个int数组就是n个插槽的标注值。插槽的顺序是从左向右。返回的字符串就是卡片的排列顺序,如果不存在解,那么返回一个空字符串。
定义:
类 CardsAndSlots
方法 public String firstValid(int[] values, String letters, int[] required)
约束:
1、卡片数量在1至50之间(包括)
2、每个卡片的值和插槽的值在1至1000之间(包括)
3、给定的字符串letters的长度、values数组的长度、required数组的长度相同
4、给定的字符串letters仅包含大写英文字母('A'-'Z')
例子:
1、values {1, 2, 3};letters "ABC";required {2, 2, 1}
Returns: "BCA"
2、values {1, 2, 3, 4, 5};letters "BBBAA";required {1, 1, 1, 1, 5}
Returns: "ABBBA"
3、values {1, 1};letters "AA";required {2, 2}
Returns: ""
【我的解答】
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- public class CardsAndSlots {
- private boolean check(int[] values, int[] required, boolean[] used) {
- List<Integer> val = new ArrayList<Integer>();
- List<Integer> req = new ArrayList<Integer>();
- int count = 0;
- for (int i = 0; i < values.length; i++) {
- if (!used[i]) {
- val.add(values[i]);
- } else {
- count++;
- }
- }
- for (int i = count; i < values.length; i++) {
- req.add(required[i]);
- }
- Collections.sort(val);
- Collections.sort(req);
- for (int i = 0; i < val.size(); i++) {
- if (val.get(i) < req.get(i))
- return false;
- }
- return true;
- }
- private int findMin(String letters, boolean[] used, boolean[] choose) {
- int index = -1;
- char c = 'Z' + 1;
- for (int i = 0; i < letters.length(); i++) {
- if (!used[i] && !choose[i] && letters.charAt(i) < c) {
- index = i;
- c = letters.charAt(i);
- }
- }
- return index;
- }
- public String firstValid(int[] values, String letters, int[] required) {
- boolean[] used = new boolean[letters.length()];
- boolean[] choose;
- StringBuilder sb = new StringBuilder();
- char c;
- int index,count=0;
- while (count++ < letters.length()) {
- choose = new boolean[letters.length()];
- for (int i = 0; i < letters.length(); i++) {
- index = findMin(letters, used, choose);
- if (index > -1) {
- choose[index] = true;
- if (values[index] >= required[sb.toString().length()]) {
- c = letters.charAt(index);
- used[index] = true;
- if (check(values, required, used))
- sb.append(c);
- else
- used[index] = false;
- }
- }
- }
- }
- return sb.toString();
- }
- }
使用循环检测的方法,即每次选择最小的字母然后检测在这个位置使用这个字母,是否会得到解,如果可以得到解就记录。
此处用到了以下事实,将values和required数组中现在可用的值(未被使用)排序,如果存在某一位置上的values的值小于required的值,那么无论怎么调整至少存在一个位置values的值将小于required的值。