• bnu A Matrix 北京邀请赛A题


    A Matrix

    2000ms
    65536KB
     
    64-bit integer IO format: %lld      Java class name: Main
    Font Size:  
    Chaos King loves permutation and matrix, now he is trying to find out some relations between them.
    Now Chaos King has a permutation. He wants to transform the permutation to a matrix by the program beneath.
    int f[][];
    int p[];
    int n;
    void insert(int r, int x)
    {
        for (int i=1; 1; i++)
            if (f[r][i]==0)
            {
                f[r][i]=x;
                return ;
            }
            else if (f[r][i]>x)
            {
                int tmp=f[r][i];
                f[r][i]=x;
                insert(r+1, tmp);
                return ;
            }
    }
    void Permutation2Matrix()
    {
        for (int i=1; i<=n; i++)
            insert(1, p[i]);
    }
    initially, all elements in f are 0.
     
    Now Chaos King has got a matrix from the program above, then he sends this matrix to you and asks you what is the initial permutation. Can you do it?

    Input

    First line of the input is an integer T indicating the number of cases,
     
    For each test case,
    • First line contains 2 integers N (1 ≤ N ≤ 105), M (1 ≤ M ≤ N) indicating length of the permutation and number of rows which do not contains 0 in the matrix.
    • Then M lines, the ith line represent the ith row in the matrix.
      • The first integer in each line is Pi, indicating the number of non-zero elements in this row. Then Pi integers, indicating those elements.
     
    It is guaranteed that ∑Pi=N and every element in the matrix is an integer in [1, N]. There are no 2 elements have the same value.
     

    Output

    For each case, first output the case number as "Case #x: ", and x is the case number.
    Then output a permutation of N, indicating the answer of this test case.
     
    If there are multiple answers, output the permutation with the largest alphabet order after reversal. (e.g. there are 2 answers: 1 2 3 and 1 3 2. After reversal, 1 2 3 becomes 3 2 1, and 1 3 2 becomes 2 3 1. Because 3 2 1 is larger than 2 3 1 in alphabet order, you should output 1 2 3)
     
    If there is no answer, output "No solution".
     

    Sample Input

    2
    3 2
    2 1 2
    1 3
    2 1
    2 2 1
     

    Sample Output

    Case #1: 1 3 2
    Case #2: No solution
    
     

    Source

     
     
    题意:程序根据一个全排列构造出矩阵,告诉你矩阵的信息,求原来可能的全排列,满足反转后字典序最大。
     
    思路:根据题意能知道信息,1.同一行的数字必须是从小到大的。同一列也是。
                   2.第i行的个数不能小于第i+1行,要满足>=.
                                         如   1 
                                               2 3 这样的情况是不能存在的,因为,因为2要被挤下来,上面必须有一个数字把它挤下来。3同理。
                 3.如果按题意来求,把所以的满足条件来求,先找出所以的可能,然后反转排序,求最满足的。10^5个,有多少可能??
                  这样的方法必须要避免。
           那我们要找到一个好的切入点来做。找出一个合适的序列顺利来求。
           例子  1 2 3 4 5 6
                   7                 可能的顺是 7  1 2 3 4 5 6   也可能 1 2 3 4 5 7 6 发现后者是最满足要求的,反转后最大。
                                      是说7出现在6前面,换一句话说,就是7要被6挤下来,而不是1 2 3 4 5当中的一个。
                所以,我们可以从最后一行,最后一列开始枚举,分别找到上一行比它小,但最大的那个数字;
                (认为就是被该数字挤下来的。)
           例子   1 2 3 4
                    5 6 7
                    8 9            变成
     
                 我们发现1是没有和谁连接的,没有关系,我们想要使反转最大,那么越小的数字出现在前面,越好,贪心的思想。
              那么原来的序列是  1 5 2 8 6 3 9 7 4 ,发现是可以的。就这样。
          但是也有一个例子是无解的。
                  1 4
                  2 3  因为3 可以连1  但是2不能连4,   4不能把2挤下去。所以2在这里发生问题了。
                         所以还需要判断上一行的数字把下一行挤下去的个数是否与下一行的个数相等。
     
    代码:
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<vector>
     6 using namespace std;
     7 
     8 vector<int>Q[100005];
     9 vector<int>Hash[100005];
    10 int hxl[100005],len;
    11 
    12 
    13 void dfs(int x,int y,int dep)
    14 {
    15     if(x>dep)return;
    16     if(Hash[x][y]==-1)
    17     {
    18         Hash[x][y]=-2;
    19         hxl[++len]=Q[x][y];
    20         return;
    21     }
    22     dfs(x+1,Hash[x][y],dep);
    23     hxl[++len]=Q[x][y];
    24     Hash[x][y]=-2;
    25 }
    26 void solve(int n,int m)
    27 {
    28     for(int i=m;i>=2;i--)
    29     {
    30         int k=Hash[i][0];
    31         int s=Hash[i-1][0];
    32         for(int j=k;j>=1;j--)
    33         {
    34             for(;s>=1;s--)
    35             if(Q[i][j]>Q[i-1][s]){
    36                 Hash[i-1][s]=j;
    37                 s--;
    38                 break;
    39             }
    40         }
    41     }
    42     for(int i=1;i<m;i++)
    43     {
    44         int num=0;
    45         for(int j=1;j<=Hash[i][0];j++)
    46             if(Hash[i][j]!=-1)num++;
    47         if(num!=Hash[i+1][0]){
    48             printf(" No solution
    ");
    49             return;
    50         }
    51     }
    52     len = 0;
    53     for(int i=1;i<=m;i++)
    54     {
    55         for(int j=1;j<=Q[i][0];j++)
    56         {
    57             if(Hash[i][j]==-1)hxl[++len]=Q[i][j];
    58             else if(Hash[i][j]==-2)continue;
    59             else dfs(i,j,m);
    60         }
    61     }
    62     for(int i=1;i<=len;i++)
    63     printf(" %d",hxl[i]);
    64     printf("
    ");
    65 }
    66 int main()
    67 {
    68     int T,n,m,x,y;
    69     scanf("%d",&T);
    70     for(int t=1;t<=T;t++)
    71     {
    72         scanf("%d%d",&n,&m);
    73         for(int i=1;i<=n;i++){
    74             Q[i].clear();
    75             Hash[i].clear();
    76         }
    77         bool flag=false;
    78         for(int i=1;i<=m;i++)
    79         {
    80             scanf("%d",&x);
    81             Q[i].push_back(x);
    82             Hash[i].push_back(x);
    83             for(int j=1;j<=x;j++)
    84             {
    85                 scanf("%d",&y);
    86                 Q[i].push_back(y);
    87                 Hash[i].push_back(-1);
    88                 if(j>1&&Q[i][j]<=Q[i][j-1]) flag=true;
    89             }
    90             if(i>1&&Q[i][0]>Q[i-1][0])flag=true;
    91         }
    92         printf("Case #%d:",t);
    93         if(flag==true)printf(" No solution
    ");
    94         else{
    95             solve(n,m);
    96         }
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    cmd输入输出重定向
    【转载】标准输入输出、错误输出、重定向标准输出
    cmd 重定向
    Windows下cmd标准输入输出重定向
    Windows 命令行输入输出重定向问题
    MATLAB数值计算与符号运算
    选择排序法 冒泡排序法 本质上是对内存进行整理
    学习笔记:Monkey runner(一)
    Monkey test
    fiddler:快速标识接口
  • 原文地址:https://www.cnblogs.com/tom987690183/p/4032215.html
Copyright © 2020-2023  润新知