51nod 1160 压缩算法的矩阵

版权声明:_ https://blog.csdn.net/lunch__/article/details/82655579

题目链接

这个题做法好神奇啊… 数据完全没有开满

我们把所输入的矩阵二的最后一列排序 那么就得到了矩阵的第一列

我们考虑从矩阵的第一列推出第 k

我们已经知道了第 k 行的第一位数是什么

然后根据它的矩阵变换规则 把第一个数移到最后一位

我们输入的序列可以知道这个数在这一行对应的第一位是什么

这样一直推下去就得出答案了 推的过程中如果出现了环那就是无解的

举个栗子来理解一下下 11100 每一个数记录下它属于哪一行
排序后得到 00111 它隶属的行随着一起排序

我们就知道了矩阵2的一部分是这样的
0 x x x 1
0 x x x 1
1 x x x 1
1 x x x 0
1 x x x 0

假设求第 2 行 我们知道了第一位是什么

把第一位的 0 移到最后一行

变成了x x x 1 0

我们再找到第二行的第一位做最后一位的时候是在哪一行

在排序的时候我们记录下了这个状态

那么那一行的开头就是接下来的一位数

自己模拟一下理解起来不是很难 然后就做完了

不知道为什么用char比int快好几倍,用int就需要基数排序了

Codes

#include<bits/stdc++.h>

using namespace std;

const int N = 500000 + 10;
pair<char, int> a[N];
int vis[N]; char ans[N];

int main() {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    int n, k; int cnt = 0;
    scanf("%d", &n), k = 1;
    for(int i = 1; i <= n; ++ i)
        cin >> a[i].first, a[i].second = i;
    sort(a + 1, a + n + 1);
    for(int i = 1; i <= n; ++ i) {
        if(vis[k]) return puts("No Solution"), 0;
        ans[++ cnt] = a[k].first;
        k = a[vis[k] = k].second;
    }
    for(int i = 1; i <= cnt; ++ i) putchar(ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lunch__/article/details/82655579