题目:
长度为N的字符串按顺序进行编号,如N=4,使用a,b,c,d,进行如下编号,求两个号码之间有多少个号码:
abcd abdc acbd acdb adbc adcb
bacd badc bcad bcda bdac bdca
cabd cadb cbad cbda cdab cdba
dabc dacb dbac dbca dcab dcba
对于第一个case => 4 adbc bdca可以从上面顺序表中看出adbc第5个编号,bdca是第12个编号,他们之间有12 - 5 -1 = 6个编号。
TestCase:
5
4 adbc bdca
5 ebdac eadcb
6 ecfabd dfcaeb
8 dgceabhf fhagbcde
10 cfhjdabegi cbhagfdije
Output:
#1 6
#2 4
#3 76
#4 10606
#5 125108
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class 全排列的字符串 {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(bf.readLine());
int T = Integer.parseInt(st.nextToken());
for (int tc = 1; tc <= T; tc++) {
st = new StringTokenizer(bf.readLine());
int N = Integer.parseInt(st.nextToken());
String s = st.nextToken();
String e = st.nextToken();
int sPos = getNo(s);
int ePos = getNo(e);
System.out.println("#"+tc+" "+ (Math.abs(ePos - sPos )- 1));
}
}
private static int getNo(String s) {
int N = s.length();
boolean visited[] = new boolean[N];
int res = 0;
for (int i = 0; i < N; i++) {
//当前字母
char cur = s.charAt(i);
//当前字母到a的距离
int dis = cur - 'a';
visited[dis] = true;
//当前位置可用的字母数量
int canUse = 0;
for (int j = 0; j < dis; j++) {
if(!visited[j]) {canUse++;}
}
//剩余的字母全排列 N!
int cnt = 1;
for(int k = N - i -1;k>=1;k--){
cnt *= k;
}
res += canUse*cnt;
}
return res + 1;
}
}