POJ 1147 Binary codes (BWT算法 很巧妙)


Binary codes
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5677 Accepted: 2213

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 string.

b1b2bN−1bN
b2b3bNb1
bN−1bNbN−3bN−2
bNb1bN−2bN−1

Figure 1. The rotated matrix

Then rows of the matrix are sorted in alphabetical order, where ‘0’ is before ‘1’. You are to write a program which, given the last column of the sorted matrix, finds the first row of the sorted matrix.

As an example, consider the string (00110). The sorted matrix is

00011
00110
01100
10001
11000

and the corresponding last column is (1 0 0 1 0). Given this last column your program should determine the first row, which is (0 0 0 1 1).

Input

The first line contains one integer N ≤ 3000, the number of binary digits in the binary string. The second line contains N integers, the binary digits in the last column from top to bottom.

Output

The first line contains N integers: the binary digits in the first row from left to right.

Sample Input

5
1 0 0 1 0

Sample Output

0 0 0 1 1

Source

IOI 2001 (back-up task)

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

题目大意:一个长度为n的二进制序列循环左移n-1次得到n个不同的序列,对这n个序列按字典序排序得到一个矩阵,给出这个矩阵的最后一列,输出其第一行

题目分析:题解PDF,很详细

#include <cstdio>
#include <cstring>
using namespace std;  
int const MAX = 3005;
int a[MAX], tmp[MAX],next[MAX];  
bool used[MAX];  
int main()  
{  
    int n, cnt = 0;  
    scanf("%d", &n);  
    memset(used, false, sizeof(used));  
    memset(tmp, 0, sizeof(tmp));  
    for(int i = 0; i < n; i++)  
    {  
        scanf("%d", &a[i]);  
        if(a[i])  
            cnt++;  
    }  
    for(int i = n - cnt; i < n; i++)  
        tmp[i] = 1;  
    for(int i = 0; i < n; i++)  
    {  
        int j = 0;  
        while(tmp[i] != a[j] || used[j])  
            j++;  
        used[j] = true;  
        next[i] = j;  
    }  
    int ind = 0;  
    for(int i = 0; i < n; i++)  
    {  
        ind = next[ind];  
        if(i != (n - 1))
            printf("%d ", a[ind]);  
        else
            printf("%d\n", a[ind]);
    }  
}  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值