• 网易2017---数列还原


    题目描述

    牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10 个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j] 的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。

    输入描述:

    每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。

    输出描述:

    输出一行表示合法的排列数目。
    示例1

    输入

    5 5
    4 0 0 2 0

    输出

    2

    题目链接

    法一:dfs,惊奇的过了。全排列的变形,具体如下。代码如下(耗时25ms):
     1 public class Main {
     2 
     3     //vis标记已经排列的数1~n,不是标记已经排列的下标!!!
     4     static boolean[] vis = null;
     5     //记录每一个可能的排列数列
     6     static int[] res = null;
     7     //最后将符合标准的排列计数
     8     static int cnt = 0;
     9     
    10     public static void main(String[] args) throws IOException {
    11         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    12         String line = in.readLine();
    13         String[] s = line.split(" ");
    14         int n = Integer.parseInt(s[0]), k = Integer.parseInt(s[1]);
    15         line = in.readLine();
    16         s = line.split(" ");
    17         vis = new boolean[n + 1];
    18         res = new int[n + 1];
    19         //初始化标记数组和结果数组,注意以下这里的下标,开始从1开始了
    20         for(int i = 0; i < n; i++) {
    21             if(!s[i].equals("0")) {
    22                 res[i + 1] = Integer.parseInt(s[i]);
    23                 vis[res[i + 1]] = true;
    24             }
    25         }
    26         dfs(1, n, k);
    27         System.out.println(cnt);
    28     }
    29     private static void dfs(int x, int n, int k) {
    30         //递归终点
    31         if(x == n + 1) {
    32             int num = 0;
    33             //校验标准是否通过,即i<j且a[i]<a[j],且对数是k
    34             for(int i = 1; i < n; i++) {
    35                 for(int j = i + 1; j < n + 1; j++) {
    36                     if(res[i] < res[j]) {
    37                         num++;
    38                     }
    39                 }
    40             } 
    41             //如果标准通过,计数cnt
    42             if(num == k) {
    43                 cnt++;
    44             }
    45             return;
    46         }
    47         //如果初始已经有值,则直接dfs下一个位置,类似于数独的初始化
    48         if(res[x] != 0) {
    49             dfs(x + 1, n, k);
    50         }
    51         //这里的i表示可排列的1~n的元数据,因为没有用数组存起来,所以这里直接从1开始
    52         for(int i = 1; i <= n; i++) {
    53             //校验当前数据是否已经在排列中,如果不在排列中,则放入排列即可
    54             if(vis[i] == false) {
    55                 vis[i] = true;
    56                 res[x] = i;
    57                 dfs(x + 1, n, k);
    58                 res[x] = 0;
    59                 vis[i] = false;
    60             }
    61         }
    62     }
    63 
    64 }
    View Code
  • 相关阅读:
    java- 输入任意数据,求和
    《大道至简》 第一章 读后感
    简易四则运算小程序二
    简易四则运算小程序
    登录界面
    《构建之法》阅读笔记六
    《构建之法》阅读笔记五
    《构建之法》阅读笔记四
    《构建之法》阅读笔记三
    《构建之法》阅读笔记二
  • 原文地址:https://www.cnblogs.com/cing/p/8629393.html
Copyright © 2020-2023  润新知