poj 1147 Binary codes BWT压缩算法

题意:一个长度为N的01序列,会有N个不同的轮换(当然,字符相同,其中也可能会有相同的),将这N个不同轮换按字典序排

序,取排序后的每个轮换的最后一排,组成一个序列。题中给出压缩后的序列,求原始序列,输出的是字典序最小的那个序列。

思路:这题基于一个性质:在已经排序好的矩阵中,对于首位相同的两行,经过左移一位的操作后,形成的新的两行的先后次序不发

生改变。即:设i行在j行前面,i行左移一位变成p行,j左移一位后变成q行,p还是在q的前面。已知最后一列,那么我们可以知道一行

有几个零(cnt0个)几个一(cnt1个),那么我们自然能得到第一列,前cnt0个为零,之后cnt1个为一。由上述性质,第一列第i个零所在的

p行一定是转移到最后一列第i个零所在的q行,且q行的首位是是p行首位的后一位。那么我们利用性质即可得到行转移的数组next。

最后沿着next进行行转移,依次输出行的首位即为第一行,详见代码:

/*********************************************************
  file name: poj1147.cpp
  author : kereo
  create time:  2015年02月21日 星期六 18时08分02秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=1000000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n,cnt0,cnt1;
int a[MAXN],num0[MAXN],num1[MAXN],next[MAXN];
int main(){
    while(~scanf("%d",&n)){
        cnt0=cnt1=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(a[i])
                cnt1++,num1[cnt1]=i;
            else
                cnt0++,num0[cnt0]=i;
        }
        for(int i=1;i<=n;i++){
            if(i<=cnt0)
                next[i]=num0[i];
            else
                next[i]=num1[i-cnt0];
        }
        int k=1,ans;
        for(int i=1;i<=n;i++){
            if(i == 1)
                printf("%d",ans=k<=cnt0 ? 0 : 1);
            else
                printf(" %d",ans=k<=cnt0 ? 0 : 1);
            k=next[k];
        }
        printf("\n");
    }
	return 0;
}
时间: 2024-10-13 18:12:56

poj 1147 Binary codes BWT压缩算法的相关文章

poj 1147 Binary codes

Binary codes Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5647   Accepted: 2201 Description Consider a binary string (b1-bN) with N binary digits. Given such a string, the matrix of Figure 1 is formed from the rotated versions of the

BWT 压缩解压缩算法介绍 poj 1147

poj上1147题, 题意:任意一个长度为N的字符串,循环左移一个字符长度,这样形成N个新字符串,将这N个字符串按字典顺序排序,从上到下取得排序后的每行最后一列的的所有字符,求排序后的第一行字符串? 举个简单例子: 原串为: 0 0 0 1 1 那么循环左移排序后的矩阵为: 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 那么我们得到最后列的字符串为: 1 0 0 1 0 现在我们只知道最后列的字符串 1 0 0 1 0,让我们求循环左移排序后

POJ 2499 Binary Tree 题解

本题使用所谓的辗转相除法. 还需要逆过来遍历二叉树.可以想象给出的数据点是根节点,然后遍历到根节点(1,1). 考的是根据给出的规则,总结规律的能力. #include <stdio.h> namespace BinaryTree2499_1 { int main() { int T, a, b, le, ri; scanf("%d", &T); for (int t = 1; t <= T; t++) { scanf("%d %d", &

POJ 1785 Binary Search Heap Construction (线段树)

题目大意: 给出的东西要求建立一个堆,使得后面的数字满足堆的性质,而且字符串满足搜索序 思路分析: 用线段树的最大询问建树.在建树之前先排序,然后用中序遍历递归输出. 注意输入的时候的技巧... #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define lson num<<1,s,mid #define rson num<<

poj 1430 Binary Stirling Numbers

Binary Stirling Numbers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1761   Accepted: 671 Description The Stirling number of the second kind S(n, m) stands for the number of ways to partition a set of n things into m nonempty subsets.

笛卡尔树 POJ ——1785 Binary Search Heap Construction

相应POJ 题目:点击打开链接 Binary Search Heap Construction Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 9075   Accepted: 2566 Description Read the statement of problem G for the definitions concerning trees. In the following we define the basic

Poj 2499 Binary Tree

题目链接:http://poj.org/problem?id=2499 思路: 结点向左边移动时结点(a, b)变为( a+b, b),向右边移动时( a, b )变为( a, a + b); 为求最短路径<a1, a2, a3,...,an>,考虑从已经知道的结点(a, b)开始找出最短路径回到根节点(1, 1): 即向左移动次数和向右移动次数最少回到根节点,由贪心算法,若 a>b 时,a 减少最大即减去 b: 若 a < b,b 减少最大即减去a值,循环直到到达根节点(1, 1

POJ 2499 Binary Tree 数学题解

Description Background Binary trees are a common data structure in computer science. In this problem we will look at an infinite binary tree where the nodes contain a pair of integers. The tree is constructed like this: The root contains the pair (1,

ACM POJ 1146 ID Codes

题目大意:输入一个字符串,输出它的下一个字典序排列. 字典序算法思想: 1.从右向左寻找字符串找出第一个a[i]<a[i+1]的位置i; 2.从右向左找出第一个大于a[j]的元素a[i]; 3.swap(a[i],a[j]) 4.将a[i]......到a[stelen(a)]倒序 5.输出a 代码如下: #include<iostream> #include<cstdio> #include <cstring> #include<algorithm>