当前位置: 代码迷 >> 综合 >> 51nod 1160 压缩算法的矩阵
  详细解决方案

51nod 1160 压缩算法的矩阵

热度:41   发布时间:2024-01-19 01:47:34.0

个二进制序列,例如: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;
}