A - green_gold_dog, array and permutation
题目描述
给你一个长度为n
的数组a
,请你构造出一个长度为n
的排列b
,使得 a i − b i a_i - b_i ai−bi的和最大。
思路:排序+技巧
- 要让排列
b
与原数组a
的差的和尽可能大,就让原数组a
中最大的数对应排列b
中最小的数。
public static void solve() throws IOException {
int n = readInt();
Pair[] pairs = new Pair[n + 1];
Arrays.setAll(pairs, g -> new Pair());
for (int i = 1; i <= n; i++) {
pairs[i].first = readInt();
pairs[i].second = i;// 存下原数组中数对应的下标
}
Arrays.sort(pairs, 1, n + 1, new Comparator<Pair>() {
@Override
public int compare(Pair o1, Pair o2) {
return o2.first - o1.first;
}
});
int[] arr = new int[n + 1];
for (int i = 1; i <= n; i++) {
// 比如数组a第三个位置的数最大,就让arr[3]=1
arr[pairs[i].second] = i;
}
for (int i = 1; i <= n; i++) {
printWriter.print(arr[i] + " ");
}
printWriter.println();
}
B - XOR Palindromes
题目描述
给你一个长度为n
的二进制字符串s
,如果有一个长度为n
的二进制字符串t
,其中包含x
个1
,使得字符串t
与字符串s
异或后为一个回文字符串,那么x
就是一个好数字。
现在请你构造出一个长度为n+1
的字符串res
,如果数字i
是好数字,那么 r e s [ i ] = 1 res[i] = 1 res[i]=1,否则 r e s [ i ] = 0 res[i] = 0 res[i]=0,其中 0 ≤ i ≤ n 0 \le i \le n 0≤i≤n。
思路:思维+分类讨论+奇偶性
- 首先求出这个字符串
s
变为回文串最少所需1
的数量minGet
- 再根据
n
的奇偶性来决定数字1
的摆放- java记得使用
StringBuilder
,否则一直 t3
public static void solve() throws IOException {
int n = readInt();
String s = (" " + readString());
int minGet = 0;
for (int i = 1; i <= (n + 1) / 2; i++) {
if (s.charAt(i) != (s.charAt(n - i + 1))) {
minGet++;
}
}
StringBuilder sb = new StringBuilder();
if ((n & 1) == 0) {// n为偶数
for (int i = 0; i <= n; i++) {// 枚举能否有 i个 1
// 首先至少要有 minGet个 1,其中 minGet是构成回文串最少所需 1的数量
// 其他的 1也就是(i - minGet)个 1一定要是偶数才行
// 比如101011,minGet的1放在2,4的位置,然后多余的1修改放在1,6即可
if (i >= minGet && i <= n - minGet && ((i - minGet) & 1) == 0) {
sb.append("1");
} else {
sb.append("0");
}
}
} else {// n为奇数
for (int i = 0; i <= n; i++) {
// 对于奇数无需((i - minGet) & 1) == 0的条件,
// 因为如果出现奇数个 1,那么用一个 1来异或中间的数即可
if (i >= minGet && i <= n - minGet) {
sb.append("1");
} else {
sb.append("0");
}
}
}
printWriter.println(sb.toString());
}