您的位置:首页 > Web前端

【POJ】3294 Life Forms

2016-02-03 21:20 477 查看
后缀数组。

/* 3294 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
#define lson            l, mid, rt<<1
#define rson            mid+1, r, rt<<1|1

const int maxl = 1005;
const int maxs = 105;
const int maxn = maxl * maxs;
char s[maxs][maxl];
int id[maxn], pos[maxn], pn;
bool visit[maxs];
int a[maxn];
int rank[maxn], height[maxn], sa[maxn];
int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
int ns, ns_;

bool cmp(int *r, int a, int b, int l) {
return r[a]==r[b] && r[a+l]==r[b+l];
}

void da(int *r, int *sa, int n, int m) {
int i, j, *x=wa, *y=wb, *t, p;

for (i=0; i<m; ++i) wc[i] = 0;
for (i=0; i<n; ++i) wc[x[i]=r[i]]++;
for (i=1; i<m; ++i) wc[i] += wc[i-1];
for (i=n-1; i>=0; --i) sa[--wc[x[i]]] = i;
for (j=1,p=1; p<n; j*=2,m=p) {
for (p=0,i=n-j; i<n; ++i) y[p++] = i;
for (i=0; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i]-j;
for (i=0; i<n; ++i) wv[i] = x[y[i]];
for (i=0; i<m; ++i) wc[i] = 0;
for (i=0; i<n; ++i) wc[wv[i]]++;
for (i=1; i<m; ++i) wc[i] += wc[i-1];
for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i];
for (t=x,x=y,y=t, x[sa[0]]=0, p=1, i=1; i<n; ++i)
x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1:p++;
}
}

void calheight(int *r, int *sa, int n) {
int i, j, k = 0;

for (i=1; i<=n; ++i) rank[sa[i]] = i;
for (i=0; i<n; height[rank[i++]]=k)
for (k?k--:0, j=sa[rank[i]-1]; r[j+k]==r[i+k]; ++k) ;
}

bool check(int b, int e) {
int cnt = 0;

memset(visit, false, sizeof(visit));
rep(i, b, e+1) {
if (!visit[id[sa[i]]]) {
visit[id[sa[i]]] = true;
++cnt;
}
}

return cnt > ns_;
}

bool judge(int bound, int n) {
bool ret = false;
int b, e;

b = e = 0;
rep(i, 1, n+1) {
if (height[i] >= bound) {
e = i;
} else {
if (check(b, e)) {
if (!ret)
pn = 0;
ret = true;
pos[pn++] = sa[b];
}
b = e = i;
}
}
if (check(b, e)) {
if (!ret)
pn = 0;
ret = true;
pos[pn++] = sa[b];
}

return ret;
}

void printSa(int n) {
for (int i=1; i<=n; ++i)
printf("%d ", sa[i]);
putchar('\n');
}

void printHeight(int n) {
for (int i=1; i<=n; ++i)
printf("%d ", height[i]);
putchar('\n');
}

void solve() {
int n = 0, ml = 0;

if (ns == 1) {
puts(s[0]);
return ;
}

rep(i, 0, ns) {
for (int j=0; ; ++j) {
if (s[i][j] == '\0') {
ml = max(ml, j);
break;
}
id
= i;
a
= s[i][j] - 'a' + 100;
++n;
}
id
= a
= i;
++n;
}

--n;
da(a, sa, n+1, 130);
calheight(a, sa, n);

#ifndef ONLINE_JUDGE
// printSa(n);
// printHeight(n);
// printf("ml = %d\n", ml);
#endif

int l = 1, r = ml, mid;
int ans = 0;
ns_ = ns >> 1;

while (l <= r) {
mid = (l + r) >> 1;
if (judge(mid, n)) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}

if (ans == 0) {
puts("?");
return ;
}

char ch;

rep(i, 0, pn) {
rep(j, 0, ans) {
ch = a[pos[i]+j] - 100 + 'a';
putchar(ch);
}
putchar('\n');
}
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int t = 0;

while (scanf("%d", &ns)!=EOF && ns) {
rep(i, 0, ns)
scanf("%s", s[i]);
if (t++)
putchar('\n');
solve();
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}


数据生成器。

from random import randint, shuffle
import shutil
import string

def GenDataIn():
with open("data.in", "w") as fout:
t = 20
bound = 10**3
lc = list(string.lowercase)
for tt in xrange(t):
n = randint(1, 10)
fout.write("%d\n" % (n))
for i in xrange(n):
length = randint(20, 50)
line = ""
for j in xrange(length):
idx = randint(0, 25)
line += lc[idx]
fout.write("%s\n" % (line))
fout.write("0\n")

def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName)

if __name__ == "__main__":
GenDataIn()
MovDataIn()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: