目录
G小红的元素交换:
题目大意:
思路解析:
我们让 i - a[i] 两个元素之间连一条边,那么 1 3 2 4 =在不考虑颜色的情况下,可以变为两个环 (1)(3 2 4),最少交换次数为2。可以发现在任意环下,如果要将环内元素变为有序的,至少需要cnt - 1次操作,cnt是环内元素的个数。
但是本题有另一个要求,即不同的颜色的元素之间才能交换,如果一个环中元素为1或者(一个环中元素大于1并且环中两个颜色的元素都有)那么这样的环1都能让其变为有序。
那么我们只需要判断哪些环是只有一个颜色的,我们将这样纯色的环,通过一次交换,让其变为混色的即可。
代码实现:
import java.io.*;
import java.util.*;
public class Main {
static long mod = (int) 1e9 + 7;
static int base = 131;
static long[] pow = new long[1000005];
static char[] s;
static int MAXN = 1000005;
public static void main(String[] args) throws IOException {
FastScanner f = new FastScanner();
PrintWriter w = new PrintWriter(System.out);
int n = f.nextInt();
int[] a = new int[n+1];
for (int i = 1; i <= n; i++) {
a[i] = f.nextInt();
}
String str = " " + f.nextString();
char[] s = str.toCharArray();
int[] vis = new int[n+1];
PriorityQueue<Integer> vh = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
PriorityQueue<Integer> vr = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
PriorityQueue<Integer> vw = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for (int i = 1; i <= n; i++) {
int[] tong = new int[26];
int pre = i;
int cnt = 0;
while (vis[pre] == 0){
tong[s[pre] - 'A']++;
vis[pre]++;
pre = a[i];
cnt ++;
}
if (tong['W' - 'A'] > 0 && tong['R' - 'A'] > 0){
vh.add(cnt);
} else if (tong['W' - 'A'] > 0) {
vw.add(cnt);
}else if (tong['R' - 'A'] > 0){
vr.add(cnt);
}
}
int res = 0;
while(!vr.isEmpty() && !vw.isEmpty() && (vr.peek() > 1 || vw.peek() > 1)){
int x = vr.poll();
int y = vw.poll();
res++;
vh.add(x + y);
}
while (!vr.isEmpty() && !vh.isEmpty()){
int x = vr.poll();
if (x == 1) break;
int y = vh.poll();
res++;
vh.add(x+y);
}
while (!vw.isEmpty() && !vh.isEmpty()){
int x = vw.poll();
if (x == 1) break;
int y = vh.poll();
res++;
vh.add(x+y);
}
for (Integer integer : vh) {
res += integer - 1;
}
if (!vr.isEmpty() && vh.isEmpty() && vr.peek() > 1) res = -1;
if (!vw.isEmpty() && vh.isEmpty() && vw.peek() > 1) res = -1;
w.println(res);
w.flush();
w.close();
}
private static class FastScanner {
final private int BUFFER_SIZE = 1 << 16;
private DataInputStream din;
private byte[] buffer;
private int bufferPointer, bytesRead;
private FastScanner() throws IOException {
din = new DataInputStream(System.in);
buffer = new byte[BUFFER_SIZE];
bufferPointer = bytesRead = 0;
}
private short nextShort() throws IOException {
short ret = 0;
byte c = read();
while (c <= ' ') c = read();
boolean neg = (c == '-');
if (neg) c = read();
do ret = (short) (ret * 10 + c - '0');
while ((c = read()) >= '0' && c <= '9');
if (neg) return (short) -ret;
return ret;
}
private int nextInt() throws IOException {
int ret = 0;
byte c = read();
while (c <= ' ') c = read();
boolean neg = (c == '-');
if (neg) c = read();
do ret = ret * 10 + c - '0';
while ((c = read()) >= '0' && c <= '9');
if (neg) return -ret;
return ret;
}
public long nextLong() throws IOException {
long ret = 0;
byte c = read();
while (c <= ' ') c = read();
boolean neg = (c == '-');
if (neg) c = read();
do ret = ret * 10 + c - '0';
while ((c = read()) >= '0' && c <= '9');
if (neg) return -ret;
return ret;
}
private char nextChar() throws IOException {
byte c = read();
while (c <= ' ') c = read();
return (char) c;
}
private String nextString() throws IOException {
StringBuilder ret = new StringBuilder();
byte c = read();
while (c <= ' ') c = read();
do {
ret.append((char) c);
} while ((c = read()) > ' ');
return ret.toString();
}
private void fillBuffer() throws IOException {
bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
if (bytesRead == -1) buffer[0] = -1;
}
private byte read() throws IOException {
if (bufferPointer == bytesRead) fillBuffer();
return buffer[bufferPointer++];
}
}
}