2018年第九屆藍橋杯Java程序設計本科B組決賽個人題解彙總:
https://blog.csdn.net/daixinliangwyx/article/details/90258768
第六題
標題:防禦力
小明最近在玩一款遊戲。對遊戲中的防禦力很感興趣。
我們認爲直接影響防禦的參數爲“防禦性能”,記作d,而面板上有兩個防禦值A和B,與d成對數關係,A=2^d,B=3^d(注意任何時候上式都成立)。
在遊戲過程中,可能有一些道具把防禦值A增加一個值,有另一些道具把防禦值B增加一個值。
現在小明身上有n1個道具增加A的值和n2個道具增加B的值,增加量已知。
現在已知第i次使用的道具是增加A還是增加B的值,但具體使用那個道具是不確定的,請找到一個字典序最小的使用道具的方式,使得最終的防禦性能最大。
初始時防禦性能爲0,即d=0,所以A=B=1。
【輸入格式】
輸入的第一行包含兩個數n1,n2,空格分隔。
第二行n1個數,表示增加A值的那些道具的增加量。
第三行n2個數,表示增加B值的那些道具的增加量。
第四行一個長度爲n1+n2的字符串,由0和1組成,表示道具的使用順序。0表示使用增加A值的道具,1表示使用增加B值的道具。輸入數據保證恰好有n1個0,n2個1。
【輸出格式】
對於每組數據,輸出n1+n2+1行,前n1+n2行按順序輸出道具的使用情況,若使用增加A值的道具,輸出Ax,x爲道具在該類道具中的編號(從1開始)。若使用增加B值的道具則輸出Bx。最後一行輸出一個大寫字母E。
【樣例輸入1】
1 2
4
2 8
101
【樣例輸出1】
B2
A1
B1
E
【樣例輸入2】
3 0
7 11 13
000
【樣例輸出2】
A1
A2
A3
E
【樣例說明】
對於第一組測試數據,操作過程如下:
操作 d A B
初始 0 1 1
B2 2 4 9
A1 3 8 27
B1 log3(29) 2^(log3(29)) 29
可以證明,這個值是最大的。
對於第二組測試數據,可見無論用什麼順序,A最後總爲32,即d總爲5,B總爲243。
【數據規模】
對於20%的數據,字符串長度<=10000;
對於70%的數據,字符串長度<=200000;
對於100%的數據,字符串長度<=2000000,輸入的每個增加值不超過2^30。
資源約定:
峯值內存消耗(含虛擬機) < 256M
CPU消耗 < 1000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。
所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。
不要使用package語句。不要使用jdk1.7及以上版本的特性。
主類的名字必須是:Main,否則按無效代碼處理。
解法:因爲d=log2(A)=log3(B)這個任何時候都成立,在對A和B進行交叉操作增加x值的時候,比如先對A操作,肯定是先增加較大的ai收益最大,因爲先增加大的ai會使d在這一次增加幅度較大,同時使B也增加較大,對於下一次增加B會有更好的收益;對B操作也是類似上面,也就是說,對ai和bi進行一個結構體排序,先按值的大小排序再按下標順序(字典序)排序。當然還有注意一種情況,就是無論用什麼順序達到的收益都是一樣的,這是在什麼情況下會這樣呢,很明顯,在連續操作某一防禦值的時候,不管先增加較大的還是較小的,在操作另一防禦值之前,該防禦值增加的總值都是一樣的,對於d和另一防禦值的總影響值也是一樣的,因此這個時候就需要按字典序順序操作了。
代碼:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;
public class MainB {
public static InputReader in = new InputReader(new BufferedInputStream(System.in));
public static PrintWriter out = new PrintWriter(System.out);
public static int n1, n2, d, a, b, len, ka, kb, k;
public static String s;
public static A[] ai = new A[2000010];
public static B[] bi = new B[2000010];
public static int[] order;
public static void main(String[] args) {
d = 0;
a = 1;
b = 1;
n1 = in.nextInt();
n2 = in.nextInt();
if (n1 == 0) s = in.nextLine();//吸取空行
for (int i = 1; i <= n1; i++) {
ai[i] = new A();
ai[i].id = i;
ai[i].value = in.nextInt();
}
if (n2 == 0) s = in.nextLine();
for (int i = 1; i <= n2; i++) {
bi[i] = new B();
bi[i].id = i;
bi[i].value = in.nextInt();
}
s = in.nextLine();
Arrays.sort(ai, 1, n1+1);
Arrays.sort(bi, 1, n2+1);
len = s.length();
ka = 1;
kb = 1;
for (int i = 0; i < len; i++) {
if (s.charAt(i) == '0') {
if (s.charAt(i) == '1') {
out.println("A" + ai[ka++].id);
out.flush();
} else {//出現連續的0
order = new int[len-i+5];
k = 0;
order[k++] = ai[ka++].id;//將這一段連續的'0'對應的id存在一個數組裏
int j = i + 1;
for (j = i+1; j < len; j++) {
if (s.charAt(j) != '0') break;
order[k++] = ai[ka++].id;
}
Arrays.sort(order, 0, k);//按id從小到大排(即字典序從小到大)
i = j - 1;//調整i,使i下一次循環是從後面第一個'1'處開始
for (j = 0; j < k; j++) {
out.println("A" + order[j]);
out.flush();
}
}
} else {
if (s.charAt(i) == '0') {
out.println("B" + bi[kb++].id);
out.flush();
} else {//出現連續的1
order = new int[len-i+5];
k = 0;
order[k++] = bi[kb++].id;//將這一段連續的'1'對應的id存在一個數組裏
int j = i + 1;
for (j = i+1; j < len; j++) {
if (s.charAt(j) != '1') break;
order[k++] = bi[kb++].id;
}
Arrays.sort(order, 0, k);//按id從小到大排(即字典序從小到大)
i = j - 1;//調整i,使i下一次循環是從後面第一個'0'處開始
for (j = 0; j < k; j++) {
out.println("B" + order[j]);
out.flush();
}
}
}
}
out.println("E");
out.flush();
out.close();
}
static class A implements Comparable<A>{
int id, value;
@Override
public int compareTo(A o) {
if (o.value - this.value != 0) {
return o.value - this.value;
} else {
return this.id - o.id;
}
}
}
static class B implements Comparable<B>{
int id, value;
@Override
public int compareTo(B o) {
if (o.value - this.value != 0) {
return o.value - this.value;
} else {
return this.id - o.id;
}
}
}
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public String nextLine() {
String str = null;
try {
str = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public Double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}
}