算法-整数论初级题目-按顺序全排列的两个字符串之间的差

题目:
长度为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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值