zoukankan      html  css  js  c++  java
  • Poj 1147 Binary codes bwt压缩算法(很巧妙的一种算法)

    题目连接:http://poj.org/problem?id=1147

    题目描述:就是求解bwt压缩算法的逆过程。

    一个长度为N的01序列,会有N个不同的轮换(当然,字符相同,其中也可能会有相同的),将这N个不同轮换按字典序排序,取排序后的每个轮换的最后一排,组成一个序列。题中给出压缩后的序列,求原始序列,输出的是字典序最小的那个序列

    解法:整个解法还挺巧妙的,具体百度上也有解释,简单的根据体重给出的例子说一下:

    0 0 0 1 1
    0 0 1 1 0
    0 1 1 0 0
    1 0 0 0 1
    1 1 0 0 0

    给出的序列中0和1的个数肯定是和原始序列一样的,即由最后一列的数据10010可知原始序列中有2个0和3个1,所以将最后一列(10010)进行排序,即可得到第一列的数据(00011)。上述5*5数组中,将最后一列的数据移到第一列,得一下序列

     

    1

    0

    0

    0

    1

    0

    0

    0

    1

    1

    0

    0

    1

    1

    0

    1

    1

    0

    0

    0

    0

    1

    1

    0

    0

    (2)

    而上述五个轮换中的第一列与第二列是可以知道的,如果要将上述五个轮换按字典序排序后变成(1),则需要进行相应转换,可知如果开头都是1或者都是0则先后顺序仍然不变,只需把①②③④⑤变成②③⑤①④即可,这个时候将(2)中的第二列(00011)与第一列(10010)同时变化,即可得到(1)中的第二列(00101),以此类推,现在(1)中的第一、二列都已经知道,按照同样的推演方式即可得到(1)中,即原始序列中的所有列的元素,即可得到原始序列。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define N 3010
     7 using namespace std;
     8 bool last[N], first[N], goal[N], temp[N];
     9 int t[N];
    10 int main(){
    11     int n, i, j, k, l;
    12     while(~scanf("%d",&n)){
    13         k=0;
    14         for(i=0;i<n;i++){
    15             scanf("%d",&last[i]);
    16             if(last[i]==0){
    17                 first[k]=last[i];
    18                 t[i] = k;
    19                 k++;
    20             }
    21         }
    22         for(i=0;i<n;i++){
    23             if(last[i]==1){
    24                 first[k]=last[i];
    25                 t[i]=k;
    26                 k++;
    27             }
    28         }
    29         goal[0]=first[0];
    30         for(j=1;j<n;j++){
    31             if(j%2){
    32                 for(i=0;i<n;i++){
    33                     temp[t[i]]=first[i];
    34                 }
    35                 goal[j] = temp[0];
    36             }
    37             else{
    38                 for(i=0;i<n;i++){
    39                     first[t[i]]=temp[i];
    40                 }
    41                 goal[j] = first[0];
    42             }
    43         }
    44         for(i=0;i<n-1;i++){
    45             printf("%d ",goal[i]);
    46         }
    47         printf("%d\n",goal[i]);
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    散列
    HDOJ 1005
    ASP.NET会话(Session)模式
    【转】SQLServer 2005新功能,一些性能方面问题,sql 经典语句
    使用委托在用户自定义控件中实现事件响应
    Web.config详解 [转]
    每个分类取最新的几条的SQL实现
    c++中const与函数一起用的时候需要注意什么?
    ASP.NET中定制自己的委托和事件参数类
    asp.net repeat嵌套
  • 原文地址:https://www.cnblogs.com/celia01/p/2435548.html
Copyright © 2011-2022 走看看