问题陈述
这是Byteland美丽的公主桑奇的结婚日。 她的未婚夫克里希纳计划给她一条很棒的红宝石项链。 Krishna目前有蓝色红宝石,g-绿色红宝石,红色红宝石 和y黄色红宝石。他必须将红宝石排列在一起 在一条直线上制作项链。但是,有几个 制作这条项链时应遵循的规则:
- 蓝宝石后面应该是蓝宝石或红宝石
- 绿宝石后面应该是绿宝石或黄宝石
- 红宝石后面应该是绿宝石或黄宝石
- 黄色红宝石后面应该是蓝宝石或红宝石
- 如果有可能,我们应该始终开始一条蓝色或红色红宝石项链
你能说出项链的最大长度是多少吗? 克里希纳可以做。项链的长度是红宝石的数量 它
输入格式
- 第一行包含一个表示b。
的整数- 第二行包含表示r。
的整数- 第三行包含一个表示y的整数。
- 第四行包含表示g。
的整数约束
- 0 <= b,r,y,g <= 2000
- b,r,y,g中的至少一个大于0
输出格式
- 单个整数,是问题的答案。
示例TestCase 1
Input 1 1 1 0 Output 3
我的解决方案:
package ruby;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class CandidateCode {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
Integer b = new Integer(br.readLine());
Integer r = new Integer(br.readLine());
Integer y = new Integer(br.readLine());
Integer g = new Integer(br.readLine());
if (b + r + y + g > 0 && b <= 2000 && b <= 2000 && r <= 2000 &&
g <= 2000 && y <= 2000 && b >= 0 && r >= 0
&& g >= 0 && y >= 0) {
ArrayList<Character> necklace = new ArrayList<Character>();
CandidateCode rn = new CandidateCode();
int length = rn.calculateLengthofNecklace(b, r, y, g,
necklace);
System.out.println(length);
}
} catch (Exception e) {
}
}
private int calculateLengthofNecklace(Integer b, Integer r, Integer y, Integer g, ArrayList<Character> necklace) {
if (anyRemaining(b))
necklace = addBlue(b, r, y, g, necklace);
else if (anyRemaining(r))
necklace = addRed(b, r, y, g, necklace);
else if (anyRemaining(g))
necklace = addGreen(b, r, y, g, necklace);
else if (anyRemaining(y))
necklace = addYellow(b, r, y, g, necklace);
// System.out.println("necklace :" + necklace.toString());
return necklace.size();
}
private ArrayList<Character> addRed(Integer b, Integer r, Integer y, Integer g, ArrayList<Character> necklace) {
char lastruby = necklace.size() > 0 && necklace.get(necklace.size() - 1) != null
? necklace.get(necklace.size() - 1) : 'z';
if (anyRemaining(r) && (lastruby == 'y' || lastruby == 'b' || lastruby == 'z')) {
necklace.add('r');
r = r - 1;
// System.out.println("in addRed\n b:" + b + " r: " + r + " y: " + y
// + " g: " + g);
} else {
return necklace;
}
ArrayList<Character> n1 = new ArrayList<Character>(necklace);
ArrayList<Character> n2 = new ArrayList<Character>(necklace);
n1 = addGreen(b, r, y, g, n1);
n2 = addYellow(b, r, y, g, n2);
necklace = n1.size() > n2.size() ? n1 : n2;
return necklace;
}
private ArrayList<Character> addYellow(Integer b, Integer r, Integer y, Integer g, ArrayList<Character> necklace) {
char lastruby = necklace.size() > 0 && necklace.get(necklace.size() - 1) != null
? necklace.get(necklace.size() - 1) : 'z';
if (anyRemaining(y) && (lastruby == 'r' || lastruby == 'g' || lastruby == 'z')) {
necklace.add('y');
y = y - 1;
// System.out.println("in addYellow\n b:" + b + " r: " + r + " y: "
// + y + " g: " + g);
} else {
return necklace;
}
ArrayList<Character> n1 = new ArrayList<Character>(necklace);
ArrayList<Character> n2 = new ArrayList<Character>(necklace);
n1 = addBlue(b, r, y, g, n1);
n2 = addRed(b, r, y, g, n2);
necklace = n1.size() > n2.size() ? n1 : n2;
return necklace;
}
private ArrayList<Character> addGreen(Integer b, Integer r, Integer y, Integer g, ArrayList<Character> necklace) {
char lastruby = necklace.size() > 0 && necklace.get(necklace.size() - 1) != null
? necklace.get(necklace.size() - 1) : 'z';
if (anyRemaining(g) && (lastruby == 'r' || lastruby == 'g' || lastruby == 'z')) {
necklace.add('g');
g = g - 1;
// System.out.println("in addGreen\n b:" + b + " r: " + r + " y: " +
// y + " g: " + g);
} else {
return necklace;
}
ArrayList<Character> n1 = new ArrayList<Character>(necklace);
ArrayList<Character> n2 = new ArrayList<Character>(necklace);
n1 = addGreen(b, r, y, g, n1);
n2 = addYellow(b, r, y, g, n2);
necklace = n1.size() > n2.size() ? n1 : n2;
return necklace;
}
private ArrayList<Character> addBlue(Integer b, Integer r, Integer y, Integer g, ArrayList<Character> necklace) {
char lastruby = necklace.size() > 0 && necklace.get(necklace.size() - 1) != null
? necklace.get(necklace.size() - 1) : 'z';
if (anyRemaining(b) && (lastruby == 'y' || lastruby == 'b' || lastruby == 'z')) {
necklace.add('b');
b = b - 1;
// System.out.println("in addBlue\n b:" + b + " r: " + r + " y: " +
// y + " g: " + g);
} else {
return necklace;
}
ArrayList<Character> n1 = new ArrayList<Character>(necklace);
ArrayList<Character> n2 = new ArrayList<Character>(necklace);
n1 = addBlue(b, r, y, g, n1);
n2 = addRed(b, r, y, g, n2);
necklace = n1.size() > n2.size() ? n1 : n2;
return necklace;
}
private boolean anyRemaining(Integer b) {
return b > 0;
}
}
这个解决方案可以做得更好吗?
答案 0 :(得分:2)
TL; DR:您可以简单地将其计算为b + g + max(2 * min(r, y), 1 + 2 * min(r - 1, y))
你实现的问题是它像疯了一样分支:如果你有大量的珠子,它将采取每个选择 - 很多选择 - 所以它需要很长时间才能完成。
我认为最长项链的实际构造实际上非常简单(即使它会导致项链暗淡)。如果你想尝试一下,我已经实现了这个here。
您可以构建所有可能转换的图表:
digraph G {
"B" -> "B"
"B" -> "R"
"G" -> "G"
"R" -> "G"
"R" -> "Y"
"G" -> "Y"
"Y" -> "B"
"Y" -> "R"
}
您只能访问这些节点中的每一个:您可以访问B
节点b
次,G
节点g
次等。
如果你每个珠子中至少有一个,你必须从B或R开始。所以,最长的项链是由:
(all B)+R+(all G)+Y+R+Y+R+...
or
R+(all G)+Y+R+Y+R+...+(all B))
其中...
表示重复Y / R交替,直到您的珠子用完为止。
所以长度是max(b + 2*min(r, y) + g, 1 + g + min(r-1, y) + b)
。
同样,如果某些数字为零,您可以考虑最佳路径。
如果你有一种零:
b=0
,请从R开始:最大长度为2*min(r, y + 1) + g
r=0
,请从B开始:最大长度为b
g=0
,请从B开始:最大长度为b + 2*min(r,y)
y=0
,请从B开始:最大长度为v + 1 + g
如果你有两种零:
b=r=0
,请从G开始:最大长度为g + 1
b=g=0
,请从R开始:最大长度为2*min(r, y + 1)
b=y=0
,请从R开始:最大长度为1 + g
r=g=0
,请从B开始:最大长度为b
r=y=0
,请从B开始:最大长度为b
g=y=0
,请从B开始:最大长度为b + 1
如果您有三种零(或者更确切地说,只有一种非零):
b != 0
,请从B开始:最大长度为b
r != 0
,请从R开始:最大长度为1
g != 0
,请从G开始:最大长度为g
y != 0
,请从Y开始:最大长度为1
。你从来没有全部4种中的零,所以没有必要考虑那里。
因此,更有效的解决方案就是检查每一种情况。
但是,如果你比较这里的所有逻辑,你会发现有一个简单的表达式涵盖了所有的情况:
b + g + max(2 * min(r, y), 1 + 2 * min(r - 1, y));
所以,只需实现它!与原始代码不同,它可以立即有效运行。
这告诉你最长项链的长度;但要建造一条满足长度的项链并不难。