算法提高 3000米排名预测

问题描述
  3000米长跑时,围观党们兴高采烈地预测着最后的排名。因为他们来自不同的班,对所有运动员不一定都了解,于是他们分别对自己了解的一些运动员的实力作出了评估,即对部分运动员做了相对排名的预测,并且告诉了可怜留守的班长。因为无聊,于是他们就组团去打Dota去了。比赛结束后他们向班长询问最后的排名,但班长不记得了,只记得他们中哪些人的预测是正确的,哪些人的预测是错误的。他们想知道比赛的排名可能是什么。
输入格式
  第一行两个整数n, m,n为运动员数量,m为围观党数量。运动员编号从0到n-1。
  接下来m行,每行为一个围观党的相对排名预测。每行第一个数c表示他预测的人数,后面跟着c个0~n-1的不同的数,表示他预测的运动员相对排名,最后还有一个数,0表示这个预测是错误的,1表示是正确的。
输出格式
  第一行一个数k为有多少种排名的可能。
  下面k行,每行一个0~n-1的排列,为某一个可能的排名,相邻的数间用空格隔开。所有排名按字典序依次输出。
样例输入
Input Sample 1:
3 2
2 0 1 1
2 1 2 0

Input Sample 2:
3 2
2 0 1 1
2 2 1 0
样例输出
Output Sample 1:
2
0 2 1
2 0 1

Output Sample 2:
1
0 1 2
数据规模和约定
  1<=n<=10, 2<=c<=n, 1<=m<=10,保证数据合法,且答案中排名可能数不超过20000。对于一个排名序列,一个预测是正确的,当且仅当预测的排名的相对顺序是排名序列的一个子序列。一个预测是错误的,当且仅当这个预测不正确。
两个关键部分:
1.对所有排名进行全排列。
2.对每一种情况进行判断,符合正确的预测,不符合错误的预测。
 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 public class Main{
 5     static int n;
 6     static int m;
 7     static int[][] a;
 8     static boolean[] c;
 9     static int[][] d;
10     static int sum;
11     public static void main(String[] args) {
12         Scanner input = new Scanner(System.in);
13         n = input.nextInt();
14         m = input.nextInt();
15         a = new int[n][10];
16         c = new boolean[n];
17         d = new int[20000][10];
18         for(int i=0;i<m;i++){
19             a[i][0] = input.nextInt();
20             for(int j=1;j<=a[i][0];j++){
21                 a[i][j] = input.nextInt();
22             }
23             a[i][a[i][0]+1] = input.nextInt();
24         }
25         int[] b = new int[n];
26         f(0,b,0);
27         System.out.println(sum);
28         for(int i=0;i<sum;i++){
29             for(int j=0;j<n;j++){
30                 System.out.print(d[i][j]+" ");
31             }
32             System.out.println();
33         }
34     }
35     public static void f(int i,int[] b,int h){
36         if(h==n){
37             if(f1(b)){
38                 for(int j=0;j<n;j++){
39                     d[sum][j] = b[j];
40                 }
41                 sum++;
42                 
43             }
44         }
45         //排名全排列
46         for(int j=0;j<n;j++){
47             if(!c[j]){
48                 c[j] = true;
49                 b[h] = j;
50                 f(j+1,b,h+1);
51                 c[j] = false;
52             }
53             
54         }
55     }
56     //对排名情况进行判断是否符合预测
57     public static boolean f1(int[] b){
58         for(int i=0;i<m;i++){
59             int j,h = 1;
60             for(j=0;j<n;j++){
61                 if(b[j]==a[i][h]){
62                     h++;
63                     if(h==a[i][0]+1)    break;
64                 }
65             }
66             //不符合预测返回false
67             if(!(h==a[i][0]+1&&a[i][a[i][0]+1]==1)&&!(h!=a[i][0]+1&&a[i][a[i][0]+1]==0)){
68                 return false;
69             }
70         }
71         return true;
72         
73     }
74 }

 

posted @ 2017-03-30 14:55  来一点音乐  阅读(513)  评论(0编辑  收藏  举报