zoukankan      html  css  js  c++  java
  • 长跑排名预测

     

    参考代码

     1 public class yucepaiming {
     2     //存储运动员数量与围观党数量
     3     private static int n,m;
     4     //存储围观党预测结果
     5     private static String[][] s;
     6     //存储运动员排名顺序
     7     private static int[] list;
     8     //存储满足预测的结果总和
     9     private static int sum;
    10     private static List<int[]> alist = new ArrayList<>();
    11     public static void main(String[] args) {
    12         String str = new Scanner(System.in).nextLine();
    13         n = Integer.parseInt(str.split(" ")[0]);
    14         m = Integer.parseInt(str.split(" ")[1]);
    15         s = new String [m][];
    16         for(int i=0;i<m;i++){
    17             str = new Scanner(System.in).nextLine();
    18             s[i]=str.split(" ");
    19         }
    20         //初始化排名,1号第一名,2号第二名...
    21         list = new int[n];
    22         for(int i=0;i<n;i++){
    23             list[i]=i;
    24         }
    25         //使用回溯算法,参数为运动员排名,0为第一名
    26         dg(0);
    27         System.out.println(sum);
    28         for(int[] a : alist){
    29             str = Arrays.toString(a);
    30             str = str.replace("[", "");
    31             str = str.replace("]", "");
    32             System.out.println(str);
    33         }
    34     }
    35     private static void dg(int index) {
    36         //当最后一个顺序已经排好并且满足预测条件的话
    37         if(index == n && filter(list)){
    38             sum++;
    39             //注意必须重新复制数组,因为存入集合中的只是数组地址。如果没有复制,当数组改变时,集合的元素也会改变
    40             alist.add(Arrays.copyOf(list, list.length));
    41         }else{
    42             /*交换顺序->排下一个运动员->还原顺序,注意当前交换顺序的运动员只能交换他后面的运动员的顺序,
    43             这样交换的两个运动员在递归过程中才不会重复交换,产生错误的数据,所以i=index,而不是0 */
    44             for(int i=index;i<n;i++){
    45                 //交换顺序
    46                 int t = list[i];
    47                 list[i] = list[index];
    48                 list[index] = t;
    49                 //排下一个运动员
    50                 dg(index+1);
    51                 //还原顺序
    52                 t = list[i];
    53                 list[i] = list[index];
    54                 list[index] = t;
    55             }
    56         }
    57     }
    58     private static boolean filter(int[] data) {
    59         boolean falg = true;
    60         for(int i=0;i<m;i++){
    61             //这个预测是错误的
    62             if(s[i][s[i].length-1].equals("0")){
    63                 //当所以运动员都满足预测则预测错误
    64                 for(int j=0,k=1;j<n;j++){
    65                     if(Integer.parseInt(s[i][k])==list[j]&&++k==s[i].length-1){
    66                         falg = false;
    67                     }
    68                 }
    69             }else{//这个预测是正确的                
    70                 falg = false;
    71                 //当所以运动员都满足预测则预测正确
    72                 for(int j=0,k=1;j<n;j++){
    73                     //原理同错误预测
    74                     if(Integer.parseInt(s[i][k])==list[j]&&++k==s[i].length-1){
    75                         falg = true;
    76                     }
    77                 }
    78             }
    79         }
    80         return falg;
    81     }
    82 }

    运行结果

     注意:

    1                 for(int j=0,k=1;j<n;j++){
    2                     if(Integer.parseInt(s[i][k])==list[j]&&++k==s[i].length-1){
    3                         falg = false;
    4                     }
    5                 }

    这段代码意思是当所以运动员都满足预测则预测错误

    别看这个if语句只有一行,逻辑还是特别复杂的
    首先要明白&&,当左边不满足,右边就不会执行了
    当第一次执行Integer.parseInt(s[i][k])==list[j]满足条件时,会把第i个围观党预测的第一个人从已经排好的数组list中找出来
    这时k为围观党预测的人在s[i][]中的下标,j为list数组中的下标,他们指的同一个运动员
    当第一个条件满足会执行++k==s[i].length-1,这句话的意思是如果++k超过了存预测部分的长度,换句话说就是当前k下标是最后一个预测
    因为s数组最后还存了一个状态,这句话的对错与否,所以s[i].length-1
    所以这个循环加上if判断的运行过程就是:
    在排名中找到第一个预测,判断这个预测是不是最后一个预测(当预测只有一个人会判断为预测错误,当然这样的预测是无意义的),
    如果是则判断为预测错误,否则判断下一个预测(k++),然后找到运动员排名位置(Integer.parseInt(s[i][k])==list[j]),
    注意循环是j++,也就是找到的运动员必须在上一个运动员后面的,这样才能满足预测
    如果找不到k则在循环结束都不可能满足++k==s[i].length-1,则说明预测正确,否则判断当前是否为最后一个,若是,则说明所有预测都成立,
    则返回预测错误,若不是最后一个,则判断下一个预测

  • 相关阅读:
    关于mysql数据库引擎MyIsam的表锁理解
    关于mysql数据库引擎InnoDB事务的表锁和行锁理解
    Linux查看端口、进程情况及kill进程
    linux 用yum安装软件和卸载软件
    VS 2017常用快捷键
    cin作为判断条件时(关于cin的理解)
    uva 101 木块问题
    Uva 10474 sort以及lower_bound的用法
    团队项目-选题报告
    第一次结对编程作业
  • 原文地址:https://www.cnblogs.com/chengpu/p/algorithm5.html
Copyright © 2011-2022 走看看