您的位置:首页 > 编程语言 > C语言/C++

51nod 1160 压缩算法的矩阵

2017-06-29 10:32 176 查看
个二进制序列,例如:10100,进行左循环移位n 次(n是二进制序列的长度),每移位一次产生一个新二进制序列。

矩阵1

10100
01001
10010
00101
01010

对这些序列排序,变成矩阵2

矩阵2

00101
01001
01010
10010
10100

提取最后一列(注意是列不是行):11000。问题是告诉你最后一列是11000,反推出矩阵2的第一行。如果没有符合条件的序列,则输出No Solution。

Input
第1行:2进制序列的长度N(N <= 500000)
第2行:01组成的2进制序列。对应矩阵2的最后1列。


Output
输出矩阵2的第1行。如果没有符合条件的序列,则输出No Solution。


Input示例
5
11000


Output示例
00101


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

BWT~

我们发现输入数据中第i位的数的下一位(就是在原串中的下一位)在所有原串的数中排第i位。所以我们把输入的串a[i]排序为c[i],那么答案第一位就是c[1],第二位是c[num[c[1]]],其中num[c[1]]表示c[1]在a[]中的位置。我们发现这个num不好求。

所以我们用pair来记录a数组。pair中包含a[i]和i两个元素。这样,排序后pair中的i就表示对应的c[i]的num。

用int记录会T得很夸张,所以我改成了char,快了好多,似乎是一个很棒的卡常技巧呢(笑

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

int n,now,num[2][2];
char s[500001],c[500001];

pair<char,int> a[500001];

int main()
{
scanf("%d%s",&n,s+1);
for(int i=1;i<=n;i++) a[i]=make_pair(s[i],i),num[0][s[i]-'0']++;
sort(a+1,a+n+1);now=1;
for(int i=1;i<=n;i++)
{
c[i]=a[now].first;num[1][c[i]-'0']++;now=a[now].second;
}
if(num[1][1]!=num[0][1] || num[1][0]!=num[0][0]) puts("No Solution");
else printf("%s",c+1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 思路 BWT