[BZOJ1692][Usaco2007 Dec]队列变换
试题描述
输入
* 第1行: 一个整数:N
* 第2..N+1行: 第i+1行仅有1个‘A‘..‘Z‘中的字母,表示队列中从前往后数第i 头奶牛名字的首字母
输出
* 第1..??行: 输出FJ所能得到的字典序最小的队列。每行(除了最后一行)输 出恰好80个‘A‘..‘Z‘中的字母,表示新队列中每头奶牛姓名的首 字母
输入示例
6 A C D B C B
输出示例
ABCBCD
数据规模及约定
见“试题描述”
题解
把串反过来接到后面跑后缀排序然后就可以知道每步去第一个还是最后一个最优了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
return x * f;
}
#define maxn 60010
char S[maxn];
int n, rank[maxn], height[maxn], sa[maxn], Ws[maxn];
bool cmp(int* a, int p1, int p2, int l) {
if(p1 + l > n && p2 + l > n) return a[p1] == a[p2];
if(p1 + l > n || p2 + l > n) return 0;
return a[p1] == a[p2] && a[p1+l] == a[p2+l];
}
void ssort() {
int *x = rank, *y = height;
int m = 0;
for(int i = 1; i <= n; i++) Ws[x[i] = S[i]]++, m = max(m, x[i]);
for(int i = 1; i <= m; i++) Ws[i] += Ws[i-1];
for(int i = n; i; i--) sa[Ws[x[i]]--] = i;
for(int j = 1, pos = 0; pos < n; j <<= 1, m = pos) {
pos = 0;
for(int i = n - j + 1; i <= n; i++) y[++pos] = i;
for(int i = 1; i <= n; i++) if(sa[i] > j) y[++pos] = sa[i] - j;
for(int i = 1; i <= m; i++) Ws[i] = 0;
for(int i = 1; i <= n; i++) Ws[x[i]]++;
for(int i = 1; i <= m; i++) Ws[i] += Ws[i-1];
for(int i = n; i; i--) sa[Ws[x[y[i]]]--] = y[i];
swap(x, y); pos = 1; x[sa[1]] = 1;
for(int i = 2; i <= n; i++) x[sa[i]] = cmp(y, sa[i], sa[i-1], j) ? pos : ++pos;
}
return ;
}
int main() {
n = read();
for(int i = 1; i <= n; i++) {
char ch[2]; scanf("%s", ch);
S[i] = ch[0];
}
for(int i = n + 1; i <= (n << 1); i++) S[i] = S[(n<<1)-i+1];
n <<= 1;
// puts(S + 1);
ssort();
for(int i = 1; i <= n; i++) rank[sa[i]] = i;
// for(int i = 1; i <= n; i++) printf("%d%c", rank[i], i < n ? ‘ ‘ : ‘\n‘);
int l = 1, r = n >> 1;
for(int i = 1; i <= (n >> 1); i++) {
if(rank[l] < rank[n-r+1]) putchar(S[l++]);
else putchar(S[r--]);
if(i % 80 == 0) putchar(‘\n‘);
}
return 0;
}
这题有毒。。。80 个字符还得换一次行。。。
原文:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/6491951.html